SQL 2008データベースプロジェクト(Visual Studio)を使用して、プロジェクトのスキーマと初期テストデータを管理しています。 atabaseプロジェクトは、SQLCMDの ":r"構文を使用する他の多くのスクリプトを含む展開後を使用します。
SQLCMD変数に基づいて特定のファイルを条件付きで含めることができるようにしたいと思います。これにより、ナイトリービルドを使用してプロジェクトを数回実行し、さまざまなバージョンのデータベース(マルチテナントシステム用)を使用してデータベースのさまざまなバージョンをセットアップできます。
私は次を試しました:
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
print 'inserting specific configuration'
:r .\Configuration1\Data.sql
END
ELSE
BEGIN
print 'inserting generic data'
:r .\GenericConfiguration\Data.sql
END
しかし、コンパイルエラーが表示されます:SQL01260:致命的なパーサーエラーが発生しました:Script.PostDeployment.sql
誰かがこのエラーを見たか、このように柔軟に展開後のスクリプトを構成できましたか?または、私はこれについて完全に間違った方法で行っていますか?
ありがとう、ロブ
追伸また、ファイルへのパスが変数になるようにこれを変更しようとしました この投稿に似ています 。しかし、これはパスが間違っているというエラーを表示します。
[〜#〜] update [〜#〜]
リンクされたスクリプトの一部にGOステートメントが必要なため、上記のif/else構文が機能しないことがわかりました。基本的に:rはスクリプトをインラインでインポートするだけなので、これは無効な構文になります。
リンクされたスクリプトにGOステートメントが必要な場合(私と同じように)、これを回避する簡単な方法はありません。結局、いくつかのポストデプロイメントスクリプトを作成し、ビルド時に主なポストデプロイメントスクリプトを上書きするようにプロジェクトを変更することになりましたビルド構成。これで必要なことはできましたが、もっと簡単な方法があるはずです!
同じことを必要とする人のために- 私はこの投稿が有用であることがわかった
したがって、私のプロジェクトには、次の展開後ファイルがあります。
次に、プロジェクトファイルの最後に以下を追加しました(右クリックしてアンロードしてから、右クリックして編集します)。
<Target Name="BeforeBuild">
<Message Text="Copy files task running for configuration: $(Configuration)" Importance="high" />
<Copy Condition=" '$(Configuration)' == 'Release' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
<Copy Condition=" '$(Configuration)' == 'Debug' " SourceFiles="Scripts\Post-Deployment\Default.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
<Copy Condition=" '$(Configuration)' == 'Configuration1' " SourceFiles="Scripts\Post-Deployment\Configuration1.Script.PostDeployment.sql" DestinationFiles="Scripts\Post-Deployment\Script.PostDeployment.sql" OverwriteReadOnlyFiles="true" />
</Target>
最後に、ソリューションで一致するビルド構成をセットアップする必要があります。
また、他の回避策を試している人のために、次のことも運なしで試しました:
プロジェクトファイルXMLをハッキングする代わりに、ファイルをコピーするためのビルド後イベントを作成します。展開後のスクリプトファイルへの正しいパスを作成できなかったため、これを機能させることができませんでした。 この接続の問題は問題を説明しています
スクリプトパスに変数を使用して、:rコマンドに渡します。しかし、このアプローチにはいくつかのエラーがありました。
noexec method を使用して問題を回避できました。
したがって、これの代わりに:
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
print 'inserting specific configuration'
:r .\Configuration1\Data.sql
END
条件を逆にして、NOEXEC ONを設定して、インポートされたステートメントをスキップします。
IF ('$(ConfigSetting)' <> 'Configuration1')
SET NOEXEC ON
:r .\Configuration1\Data.sql
SET NOEXEC OFF
後続のステートメントを実行する場合は、必ずオフにしてください。
リリース後の構成ではなく、デバッグ用のテストデータを展開するために、展開後プロセス内で条件付き展開を処理する方法を次に示します。
まず、ソリューションエクスプローラーでプロジェクトプロパティフォルダーを開き、右クリックして新しいSqlCmd.variablesファイルを追加します。
ファイルに_Debug.sqlcmdvars
_という名前を付けます。
ファイル内にカスタム変数を追加し、$(BuildConfiguration)
という最終変数を追加して、値をDebugに設定します。
$(BuildConfiguration)
をReleaseに設定して、Release.sqlcmdvarsを作成するプロセスを繰り返します。
次に、構成を構成します。プロジェクトのプロパティページを開き、[展開]タブを開きます。上部のドロップダウンで、構成をデバッグに設定します。一番下のドロップダウン(Sqlコマンド変数)で、ファイルをProperties\Debug.sqlcmdvarsに設定します。
次のリリースとして繰り返します:上部のドロップダウンで、構成をリリースに設定します。下部のドロップダウン(Sqlコマンド変数)で、ファイルをProperties\Release.sqlcmdvarsに設定します。
これで、Script.PostDeployment.sqlファイル内で、次のような条件付きロジックを指定できます。
_IF 'Debug' = '$(BuildConfiguration)'
BEGIN
PRINT '***** Creating Test Data for Debug configuration *****';
:r .\TestData\TestData.sql
END
_
ソリューションエクスプローラーで、最上位のソリューションを右クリックし、構成マネージャーを開きます。ビルドでアクティブにする構成を指定できます。 MSBUILD.EXEコマンドラインで構成を指定することもできます。
開発者ビルドにはテストデータがありますが、リリースビルドはありません!
Robがうまくいったため、リンクされたSQLスクリプトではGOステートメントを使用できません。これにより、BEGIN/ENDステートメント内に入れ子になります。
ただし、彼には別の解決策があります-可能であれば、参照されているスクリプトからGOステートメントを削除し、ENDステートメントの後に単一のステートメントを配置します。
IF '$(DeployTestData)' = 'True'
BEGIN
:r .\TestData\Data.sql
END
GO -- moved from Data.sql
sqlcmdvarsファイルに$(DeployTestData)という名前の新しい変数を作成したことに注意してください。これにより、テストスクリプトの展開をオンまたはオフにできます。
MSDNブログのハック が見つかりましたが、これはかなりうまくいきました。秘Theは、コマンドを一時スクリプトファイルに書き込み、代わりにそのスクリプトを実行することです。基本的に、SQLCMDの動的SQLと同等です。
_-- Helper newline variable
:setvar CRLF "CHAR(13) + CHAR(10)"
GO
-- Redirect output to the TempScript.sql file
:OUT $(TEMP)\TempScript.sql
IF ('$(ConfigSetting)' = 'Configuration1')
BEGIN
PRINT 'print ''inserting specific configuration'';' + $(CRLF)
PRINT ':r .\Configuration1\Data.sql' + $(CRLF)
END
ELSE
BEGIN
PRINT 'print ''inserting generic data'';' + $(CRLF)
PRINT ':r .\GenericConfiguration\Data.sql' + $(CRLF)
END
GO
-- Change output to stdout
:OUT stdout
-- Now execute the generated script
:r $(TEMP)\TempScript.sql
GO
_
_TempScript.sql
_ファイルには次のいずれかが含まれます。
_print 'inserting specific configuration';
:r .\Configuration1\Data.sql
_
または
_print 'inserting generic data';
:r .\GenericConfiguration\Data.sql
_
$(ConfigSetting)
の値に応じて、実行時にGO
ステートメントなどに問題はありません。
ロブ・バードのソリューションに触発されました。ただし、ビルドイベントを使用して、選択したビルド構成に基づいて展開後のスクリプトを置き換えるだけです。