24

Visual Studio データベース プロジェクトを使用して、ソース管理された静的データをデータベースにどのように入力しますか? 私は以下の 3 つの戦略をすべて試しましたが、それぞれが最後の戦略よりも徐々に優れていることがわかりました。戦略 3 を使用していますが、完全には満足していません。別の選択肢はありますか?

  1. 挿入スクリプトを「Data Generation Plans」フォルダーに配置します。「Script.PostDeployment.sql」ファイル内のスクリプトを参照して、デプロイメント プロセスに含めます。

    -- 利点: 単純
    明快 -- 欠点: slooooooow
    -- 欠点: 後続のデプロイでは、最初に静的データを削除するか、データが存在しないことを確認する必要がある => 非効率的

  2. 最初は、最も便利な方法 (SSMS 編集テーブル機能など) を使用して、データをデータベースに挿入します。bcp コマンド ライン ユーティリティを使用してそのデータを抽出し、一連のデータ ファイルを作成してプロジェクトに追加します。各データ ファイルに対して「一括挿入」ステートメントを実行する「Scripts.PostDeployment.sql」ファイルで参照されるスクリプトを作成します。

    -- 利点: insert ステートメントよりもはるかに高速です
    -- 利点: SSMS 編集テーブル機能を利用できます
    -- 欠点: 各一括挿入ステートメントには、データ ファイルの完全修飾ファイル名が必要です。 :\Projects\Dev\Source\foo.dat" の場合、リモート開発マシンもその場所に配置する必要があります。そうしないと、一括挿入ステートメントが失敗します
    -- 欠点: 後続のデプロイで一括挿入ステートメントを実行する前に、既存の静的データを削除する必要があります

  3. 配置中に一時テーブルを作成して静的データを保持し、SQL マージ ステートメントを使用してこれらのテーブルをターゲット テーブルと同期します。これらのブログ投稿のいずれかを参照してください。

    -- 利点: SQL マージは問題に対して完璧なセマンティクスを持っているようです
    -- 欠点: この戦略のロジックは各ファイルで繰り返されます -- 欠点: テーブル定義は SQL マージ ファイルの一時テーブルとして繰り返されます

優れた代替戦略はありますか? 戦略 1 は遅すぎたので断念しました。完全修飾ファイル名の問題があるため、戦略 2 は嫌いです。戦略 3 には満足していますが、興奮はしていません。ベスト プラクティスはありますか?

4

4 に答える 4

8

insert.sql スクリプトでは、GUID を [__RefactorLog] テーブル (デプロイで使用されるシステム テーブル) に配置し、次のようにデータを挿入する前に、この GUID が存在するかどうかを確認できます。

:setvar SOMEID "784B2FC9-2B1E-5798-8478-24EE856E62AE" //VS2010 で Tools\CreateGuid を使用して GUID を作成

存在しない場合 (SELECT [OperationKey] FROM [dbo].[__RefactorLog] where [OperationKey] = '$(SOMEID )')

始める

...

INSERT INTO [dbo].[__RefactorLog] ([OperationKey] ) values( '$(SOMEID )' )

終わり

次に、存在しない場合、または必要な場合にのみデータを挿入します (Guid を変更することにより)。

于 2011-03-08T14:16:40.223 に答える
2

これは、他の誰かがこれを便利だと思った場合に備えて、この問題を解決した方法です...

戦略は、データベース プロジェクトを構築する前に sqlcmdvars 変数を設定することです。この変数には、デプロイ後のスクリプトから参照できるビルド フォルダーへの絶対パスが含まれます。次に、必要な追加のファイルまたはリソースの展開スクリプトでそれを使用するのは簡単なことです。この戦略の利点は、すべてのパスがハードコードされた共有パスを要求するのではなく、プロジェクト ファイルに対して相対的であることです。

新しい SQL コマンド変数名 $(MSBuildProjectDirectory) を作成します。これは、ビルド前のスクリプトでオーバーライドされます。

sql コマンド変数を設定してデータベースを構築する msbuild スクリプトを作成します。

<Project ToolsVersion="4.0" DefaultTargets="BuildDatabase"  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
<PropertyGroup>
    <DatabaseServer>(Local)</DatabaseServer>
    <DeploymentConnectionString>Data Source=$(DatabaseServer)%3BIntegrated Security=True%3BPooling=False</DeploymentConnectionString>
    <Configuration>Release</Configuration>
</PropertyGroup>
<Target Name="BuildDatabase">
    <!-- Sets the projet path variable so that the post deployment script can determine the location of the bulk insert csv files. -->
    <XmlUpdate
        Prefix="urn"
        Namespace="urn:Microsoft.VisualStudio.Data.Schema.Package.SqlCmdVars"
        XmlFileName="$(MSBuildProjectDirectory)\DatabaseProjectName\Properties\Database.sqlcmdvars"
        XPath="/urn:SqlCommandVariables/urn:Properties/urn:Property[urn:PropertyName='MSBuildProjectDirectory']/urn:PropertyValue"
        Value="$(MSBuildProjectDirectory)\DatabaseProjectName" />

    <MSBuild
            Projects="DatabaseProjectName\DatabaseProjectName.dbproj"
            Properties="Configuration=$(Configuration);
                    TargetDatabase=DatabaseName;
                    TargetConnectionString=$(DeploymentConnectionString);
                    GenerateDropsIfNotInProject=True;
                    BlockIncrementalDeploymentIfDataLoss=False;
                    DeployToDatabase=True;
                    IgnorePermissions=True"
            Targets="Build;Deploy">
        <Output TaskParameter="TargetOutputs" ItemName="SqlFiles"/>
    </MSBuild>
</Target>

デプロイ後のスクリプトを次のように更新します...

BULK INSERT [dbo].[TableName] FROM '$(MSBuildProjectDirectory)\Scripts\Post-Deployment\Data\YourDataFile.csv'
WITH (FIELDTERMINATOR = ',', ROWTERMINATOR='\n')
于 2013-11-29T20:03:06.930 に答える
1

データベースプロジェクトからのスキーマ出力を使用して、ターゲットデータベースを更新できます。vs2010IDEを考慮していない他のマシンで実行するためのcmdツールがあります。

したがって、いずれかの列にドロップがない限り、データは同じままです。

于 2011-05-05T02:08:37.797 に答える
0

VS 2010 db プロジェクトはまだ本番環境に移行していませんが、社内プロジェクトでは、本番データベースをターゲット データベースにロードし、開発/テスト フェーズでビルド/デプロイします。そうは言っても、複数の製品データベースとそれぞれに送信される静的データがある場合、おそらくティムにとってはうまくいかないことを理解しています。しかし、私たちのような単一の製品データベース ショップでは実行できます。

于 2011-02-28T20:36:32.073 に答える