テスト環境にデータベース ロール メンバーシップを配置する

作成者: Jason Lee

このトピックでは、テスト環境へのソリューション展開の一環として、データベース ロールにユーザー アカウントを追加する方法について説明します。

データベース プロジェクトを含むソリューションをステージング環境または運用環境にデプロイする場合、通常、開発者はデータベース ロールへのユーザー アカウントの追加を自動化しないようにします。 ほとんどの場合、開発者はどのユーザー アカウントをどのデータベース ロールに追加する必要があるかわからないため、これらの要件はいつでも変更される可能性があります。 ただし、データベース プロジェクトを含むソリューションを開発環境またはテスト環境にデプロイする場合、通常、状況はかなり異なります。

  • 開発者は通常、ソリューションを定期的に(多くの場合、1 日に数回) 再デプロイします。
  • 通常、データベースはすべてのデプロイで再作成されます。つまり、データベース ユーザーは、デプロイのたびに作成され、ロールに追加される必要があります。
  • 通常、開発者はターゲットの開発環境またはテスト環境を完全に制御できます。

このシナリオでは、多くの場合、データベース ユーザーを自動的に作成し、デプロイ プロセスの一環としてデータベース ロール メンバーシップを割り当てることが有益です。

重要な要因は、この操作がターゲット環境に基づいて条件付きである必要があるということです。 ステージング環境または運用環境にデプロイする場合は、操作をスキップします。 開発者またはテスト環境にデプロイする場合は、それ以上の介入なしにロール メンバーシップをデプロイする必要があります。 このトピックでは、この課題に対処するために使用できる 1 つのアプローチについて説明します。

このトピックでは、Fabrikam, Inc という架空の会社のエンタープライズ展開要件に基づく一連のチュートリアルの一部を構成します。このチュートリアル シリーズでは、サンプル ソリューションである Contact Manager ソリューションを使用して、ASP.NET MVC 3 アプリケーション、Windows Communication Foundation (WCF) サービス、データベース プロジェクトなど、複雑さの現実的なレベルの Web アプリケーションを表します。

これらのチュートリアルの中心にある配置方法は、「プロジェクト ファイルの 理解」で説明されている分割プロジェクト ファイルのアプローチに基づいています。この方法では、ビルド プロセスは 2 つのプロジェクト ファイルによって制御されます。1 つは、すべての移行先環境に適用されるビルド命令を含み、1 つは環境固有のビルドと配置設定を含みます。 ビルド時に、環境固有のプロジェクト ファイルが環境に依存しないプロジェクト ファイルにマージされ、ビルド手順の完全なセットが形成されます。

タスクの概要

このトピックは次のことを前提としています。

  • 「プロジェクト ファイルについて」の説明に従って、分割 プロジェクト ファイルのアプローチを使用してソリューションを配置します。
  • 「ビルド プロセスについて」の説明に従って、プロジェクト ファイルから VSDBCMD を呼び出してデータベース プロジェクトを配置します。

データベース プロジェクトをテスト環境に配置するときにデータベース ユーザーを作成し、ロール メンバーシップを割り当てるには、次の操作を行う必要があります。

  • 必要なデータベース変更を行う Transact 構造化照会言語 (Transact-SQL) スクリプトを作成します。
  • sqlcmd.exe ユーティリティを使用して SQL スクリプトを実行するMicrosoft Build Engine (MSBuild) ターゲットを作成します。
  • ソリューションをテスト環境にデプロイするときにターゲットを呼び出すようにプロジェクト ファイルを構成します。

このトピックでは、これらの各手順を実行する方法について説明します。

データベース ロール メンバーシップのスクリプト作成

Transact-SQL スクリプトは、さまざまな方法で作成でき、任意の場所で作成できます。 最も簡単な方法は、Visual Studio 2010 でソリューション内にスクリプトを作成することです。

SQL スクリプトを作成するには

  1. [ソリューション エクスプローラー] ウィンドウで、データベース プロジェクト ノードを展開します。

  2. [スクリプト] フォルダーを右クリックし、[追加] をポイントして、[新しいフォルダー] をクリックします。

  3. フォルダー名として 「Test 」と入力し、Enter キーを押します。

  4. [テスト] フォルダーを右クリックし、[追加] をポイントして、[スクリプト] をクリックします。

  5. [ 新しい項目の追加 ] ダイアログ ボックスで、スクリプトにわかりやすい名前 ( AddRoleMemberships.sql など) を指定し、[ 追加] をクリックします。

    [新しい項目の追加] ダイアログ ボックスで、スクリプトにわかりやすい名前 (AddRoleMemberships.sql など) を指定し、[追加] をクリックします。

  6. AddRoleMemberships.sql ファイルで、次の Transact-SQL ステートメントを追加します。

    1. データベースにアクセスするSQL Server ログインのデータベース ユーザーを作成します。
    2. 必要なデータベース ロールにデータベース ユーザーを追加します。
  7. ファイルは次のようになります。

    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
    
  8. ファイルを保存します。

ターゲット データベースでのスクリプトの実行

データベース プロジェクトを配置するときに、配置後スクリプトの一部として必要な Transact-SQL スクリプトを実行するのが理想的です。 ただし、デプロイ後のスクリプトでは、ソリューション構成またはビルド プロパティに基づいてロジックを条件付きで実行することはできません。 代わりに、sqlcmd.exe コマンドを実行する Target 要素を作成して、MSBuild プロジェクト ファイルから直接 SQL スクリプトを実行することもできます。 このコマンドを使用して、ターゲット データベースでスクリプトを実行できます。

sqlcmd.exe –S [Database server] –d [Database name] –i [SQL script]

Note

sqlcmd コマンド ライン オプションの詳細については、「 sqlcmd ユーティリティ」を参照してください。

MSBuild ターゲットにこのコマンドを埋め込む前に、スクリプトを実行する条件を考慮する必要があります。

  • ターゲット データベースは、ロール メンバーシップを変更する前に存在している必要があります。 そのため、データベースのデプロイ にこのスクリプトを実行する必要があります。
  • スクリプトがテスト環境でのみ実行されるように条件を含める必要があります。
  • "what if" デプロイを実行している場合 、つまり、デプロイ スクリプトを生成しているが実際には実行していない場合は、SQL スクリプトを実行しないでください。

Contact Manager サンプル ソリューションで示されているように、「 プロジェクト ファイルの理解」で説明されている分割プロジェクト ファイルのアプローチを使用している場合は、次のように 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 スクリプトの場所を指定する必要があります。 これらのプロパティは、移行先の環境に関係なく同じままです。 sqlcmd コマンドを実行するには、MSBuild ターゲットを作成する必要もあります。

<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>

まとめ

このトピックでは、データベース プロジェクトを配置するときに、配置後アクションとしてデータベース ユーザーとロール メンバーシップを追加する方法の 1 つについて説明しました。 これは通常、テスト環境でデータベースを定期的に再作成する場合に便利ですが、通常はデータベースをステージング環境または運用環境にデプロイするときに避ける必要があります。 そのため、必要な条件付きロジックを使用して、データベース ユーザーとロール メンバーシップが適切な場合にのみ作成されるようにする必要があります。

もっと読む

VSDBCMD を使用してデータベース プロジェクトをデプロイする方法の詳細については、「データベース プロジェクト の配置」を参照してください。 さまざまなターゲット環境に対するデータベースデプロイのカスタマイズに関するガイダンスについては、「 複数環境のデータベースデプロイのカスタマイズ」を参照してください。 カスタム MSBuild プロジェクト ファイルを使用して配置プロセスを制御する方法の詳細については、「 プロジェクト ファイル について」および「 ビルド プロセスについて」を参照してください。 sqlcmd コマンド ライン オプションの詳細については、「 sqlcmd ユーティリティ」を参照してください。