將資料庫角色成員資格部署到測試環境
演講者:Jason Lee
本主題描述了如何在將解決方案部署到測試環境的過程中,將使用者帳戶新增至資料庫角色。
當您將包含資料庫專案的解決方案部署到預備或生產環境時,通常不希望開發人員自動將使用者帳戶新增至資料庫角色。 在大多數情況下,開發人員不知道哪些使用者帳戶需要新增到哪些資料庫角色,而這些要求可能隨時會變更。 但是,當您將包含資料庫專案的解決方案部署到開發或測試環境時,情況通常會有所不同:
- 開發人員通常會定期重新部署解決方案,通常是一天幾次。
- 通常在每次部署時重新建立資料庫,這代表每次部署後都必須建立資料庫使用者並將其新增至角色。
- 開發人員通常可以完全控制目標開發或測試環境。
在這種情況下,作為部署程序的一部分,自動建立資料庫使用者並指派資料庫角色成員資格通常會很有幫助。
關鍵是這個操作需要根據目標環境有條件。 如果您要部署到預備或生產環境,則需要跳過該操作。 如果您要部署到開發人員或測試環境,您希望無需進一步干預即可部署角色成員資格。 本主題介紹了一種可用於應對此挑戰的方法。
本主題圍繞著一家名為 Fabrikam, Inc. 的虛構公司展開,針對其企業部署需求而設計了一系列教學課程。本教學課程系列使用範例解決方案 (連絡人管理員解決方案) 來代表具有現實複雜性的 Web 應用程式,其中包括 ASP.NET MVC 3 應用程式、Windows Communication Foundation (WCF) 服務,和資料庫專案。
這些教學課程的核心部署方法是根據「了解專案檔案」中所述的分割專案檔案方法,其中建置程序由兩個專案檔案控制,一個包含適用於所有目標環境的建置指令,另一個則包含環境專屬的建置和部署設定。 在建置時,環境專屬的專案檔案被合併到與環境無關的專案檔案中,以形成完整的建置指令集。
任務概述
本主題假設:
要在將資料庫專案部署到測試環境時建立資料庫使用者並指派角色成員資格,您需要:
- 建立 Transact 結構化查詢語言 (Transact-SQL) 指令碼來進行必要的資料庫變更。
- 建立使用 sqlcmd.exe 公用程式執行 SQL 指令碼的 Microsoft Build 引擎 (MSBuild) 目標。
- 設定專案檔案以在將解決方案部署到測試環境時呼叫目標。
本主題將示範如何執行其中每個流程。
編寫資料庫角色成員資格指令碼
您可以透過多種不同的方式在您選擇的任何位置建立 Transact-SQL 指令碼。 最簡單的方法是在 Visual Studio 2010 的解決方案中建立指令碼。
要建立 SQL 指令碼
在「方案總管」視窗中,展開資料庫專案節點。
以滑鼠以滑鼠右鍵按一下「指令碼」資料夾,指向「新增」,然後按一下「新資料夾」。
鍵入 Test 作為資料夾名稱,然後按 Enter。
以滑鼠以滑鼠右鍵按一下「Test」資料夾,指向「新增」,然後按一下「指令碼」。
在「新增項目」對話方塊中,為指令碼指定一個有意義的名稱 (例如,AddRoleMemberships.sql),然後按一下「新增」。
在 AddRoleMemberships.sql 檔案中,加入 Transact-SQL 陳述式:
- 為將存取資料庫的 SQL Server 登入名稱建立資料庫使用者。
- 將資料庫使用者新增至任何所需的資料庫角色。
該文件應類似以下內容:
USE $(DatabaseName) GO CREATE USER [FABRIKAM\TESTWEB1$] FOR LOGIN[FABRIKAM\TESTWEB1$] GO USE [ContactManager] GO EXEC sp_addrolemember N'db_datareader', N'FABRIKAM\TESTWEB1$' GO USE [ContactManager] GO EXEC sp_addrolemember N'db_datawriter', N'FABRIKAM\TESTWEB1$' GO
儲存檔案。
在目標資料庫上執行指令碼
理想情況下,在部署資料庫專案時,您應該將任何必要的 Transact-SQL 指令碼作為部署後指令碼的一部分執行。 但是,部署後指令碼不允許您根據解決方案設定或建置屬性有條件地執行邏輯。 另一種方法是透過建立執行 sqlcmd.exe 命令的 Target 元素,直接從 MSBuild 專案檔案執行 SQL 指令碼。 您可以使用此命令在目標資料庫上執行指令碼:
sqlcmd.exe –S [Database server] –d [Database name] –i [SQL script]
注意
有關 sqlcmd 命令列選項的詳細資訊,請參閱 sqlcmd 公用程式。
將此命令嵌入 MSBuild 目標之前,您需要考慮您希望指令碼在什麼條件下執行:
- 在更改其角色成員資格之前,目標資料庫必須存在。 因此,您需要在部署資料庫之後執行此指令碼。
- 您需要包含一個條件,以便指令碼僅在測試環境中執行。
- 如果您正在執行「假設狀況」部署 (換句話說,如果您正在產生部署指令碼但並未實際執行它們),則不應執行 SQL 指令碼。
如果您使用「了解專案檔案」中所述的分割專案檔案方法 (如連絡人管理員範例解決方案所示),則可以分割 SQL 指令碼的建置指令,如下所示:
- 任何必要的環境專屬的屬性,以及確定是否部署權限的屬性都應放入環境專屬的專案檔案 (例如,Env-Dev.proj)。
- MSBuild 目標本身以及任何在目標環境之間不會改變的屬性,應該放在通用專案檔案中 (例如 Publish.proj) 中。
在環境專屬的專案檔案中,您需要定義資料庫伺服器名稱、目標資料庫名稱和一個布林屬性,該屬性允許使用者指定是否部署角色成員資格。
<PropertyGroup>
<CmTargetDatabase Condition=" '$(CmTargetDatabase)'=='' ">
ContactManager
</CmTargetDatabase>
<DatabaseServer Condition=" '$(DatabaseServer)'=='' ">
TESTDB1
</DatabaseServer>
<DeployTestDBRoleMemberships Condition="'$(DeployTestDBRoleMemberships)'==''">
true
</DeployTestDBRoleMemberships>
</PropertyGroup>
在通用專案文件中,您需要提供 sqlcmd 可執行檔的位置以及要執行的 SQL 指令碼的位置。 無論目標環境如何,這些屬性都將保持不變。 您還需要建立 MSBuild 目標來執行 sqlcmd 命令。
<PropertyGroup>
<SqlCmdExe Condition=" '$(SqlCmdExe)'=='' ">
C:\Program Files\Microsoft SQL Server\100\Tools\Binn\sqlcmd.exe
</SqlCmdExe>
</PropertyGroup>
<Target Name="DeployTestDBPermissions"
Condition=" '$(DeployTestDBRoleMemberships)'=='true' AND
'$(Whatif)'!='true' ">
<PropertyGroup>
<SqlScript>
$(SourceRoot)ContactManager.Database\Scripts\Test\AddRoleMemberships.sql
</SqlScript>
<_Cmd>"$(SqlCmdExe)" -S "$(DatabaseServer)"
-d "$(CmTargetDatabase)"
-i "$(SqlScript)"
</_Cmd>
</PropertyGroup>
<Exec Command="$(_Cmd)" ContinueOnError="false" />
</Target>
請注意,您將 sqlcmd 可執行檔的位置新增為靜態屬性,因為這可能對其他目標有用。 相反,您可以將 SQL 指令碼的位置和 sqlcmd 命令的語法定義為目標內的動態屬性,因為在執行目標之前不需要它們。 在這種情況下,只有在滿足下列條件時才會執行 DeployTestDBPermissions 目標:
- DeployTestDBRoleMemberships 屬性設定為 True。
- 使用者尚未指定 WhatIf=True 標幟。
最後,別忘了叫用目標。 在 Publish.proj 檔案中,您可以透過將目標新增至預設 FullPublish 目標的依賴項清單來執行此操作。 您需要確保在執行 PublishDbPackages 目標之前不會執行 DeployTestDBPermissions 目標。
<Project ToolsVersion="4.0"
DefaultTargets="FullPublish"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<PropertyGroup>
<FullPublishDependsOn>
Clean;
BuildProjects;
GatherPackagesForPublishing;
PublishDbPackages;
DeployTestDBPermissions;
PublishWebPackages;
</FullPublishDependsOn>
</PropertyGroup>
<Target Name="FullPublish" DependsOnTargets="$(FullPublishDependsOn)" />
</Project>
結論
本主題介紹了一種方法,可在部署資料庫專案時,新增資料庫使用者和角色成員資格作為部署後動作。 當您在測試環境中定期重新建立資料庫時,這通常很有用,但當您將資料庫部署到預備或生產環境時應避免這樣做。 因此,您應該確保使用必要的條件邏輯,以便僅在適當的時候建立資料庫使用者和角色成員資格。
深入閱讀
有關使用 VSDBCMD 部署資料庫專案的更多資訊,請參閱「部署資料庫專案」。 如需為不同目標環境自訂資料庫部署的指南,請參閱「為多個環境自訂資料庫部署」。 有關使用自訂 MSBuild 專案文件控制部署程序的詳細資訊,請參閱「了解專案檔案」和「了解建置程序」。 有關 sqlcmd 命令列選項的詳細資訊,請參閱 sqlcmd 公用程式。