web-dev-qa-db-ja.com

SSDTパブリッシングが列を削除しないようにする方法

完全なスキーマ比較を実行するパブリッシングプロファイルを作成したいのですが、パブリッシュしても、古いバージョンと新しいバージョンの間で削除されたテーブルや列は削除されません。

設定でBLOCK可能なデータ損失オプションを知っています。これは、DATAが失われる場合に備えて、公開プロセスを停止します。したがって、問題は、スキーマのアップグレードプロセスが中断されるか(どこにもないですか?)、または完了しますが、影響を受けるテーブルは除外されますか?

テーブルで列が追加および削除された場合、データ損失の可能性があるため、データ損失オプションのブロックによりスキーマの更新が停止されますが、新しい列はスキーマに追加されますか?

EDIT 09.08.2016:

背景に関する追加情報で質問を補足するために、これらのリンクを追加したいと思いました。

7
Magier

この質問には3つの部分があるため、「データ損失時のブロック」オプション、テーブルの削除、列の削除から始めましょう。

「潜在的なデータ損失のブロック」オプション

「データ損失が発生する可能性がある場合、増分展開をブロックする」オプションを有効にした場合:

  • 「プロジェクトのプロパティ」の「デバッグ」タブ
  • /p:BlockOnPossibleDataLoss=Trueコマンドラインオプションの使用
  • パブリッシュ構成ファイルで<BlockOnPossibleDataLoss>True</BlockOnPossibleDataLoss>を指定する

sSDTは、影響を受ける各テーブルのステートメントを次のようにスクリプト化します。

/*
The column [dbo].[Table1].[New2] is being dropped, data loss could occur.
*/
IF EXISTS (select top 1 1 from [dbo].[Table1])
    RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT
GO

/*
Table [dbo].[DontDropMe] is being dropped.  Deployment will halt if the table contains data.
*/
IF EXISTS (select top 1 1 from [dbo].[DontDropMe])
    RAISERROR (N'Rows were detected. The schema update is terminating because data loss might occur.', 16, 127) WITH NOWAIT
GO

これらのステートメントはインクリメンタルに配置されます** 他のすべての変更よりも先に配置/公開スクリプト。これにより、これらのテーブルのいずれかに行が見つかった場合、パブリッシュプロセスが完全に停止します。したがって、「データ損失時にブロック」オプションを使用する場合、部分的な配置などはありません。

** 「作成」スクリプトは常にデータベースを削除して再作成するため、失われるデータはありません;-)。

モデルから削除されたが、まだターゲット内にあるテーブル

デフォルトでは、オブジェクト(および列はオブジェクトではありません)はターゲットから削除されません。ターゲットに存在するがモデルにないオブジェクトは、次の場合にのみ削除されます。

  • 「プロジェクトのプロパティ」の「デバッグ」タブで「ターゲットではなくオブジェクトではないオブジェクトをドロップする」オプションを有効にする
  • /p:DropObjectsNotInSource=Trueコマンドラインオプションを使用する
  • パブリッシュ構成ファイルで<DropObjectsNotInSource>True</DropObjectsNotInSource>を指定します

「ソースにないオブジェクトの削除」オプションを使用しているが、テーブルのみの削除を防ぎたい場合は、次の方法で除外できます。

  • [詳細な展開設定]([プロジェクトのプロパティ]の[デバッグ]タブにある[詳細...]ボタン)に移動し、[削除]タブに移動して、[テーブルを削除しない]オプションを有効にします(スクロール可能なリスト)。
  • /p:DoNotDropObjectType=Tablesコマンドラインオプションの使用
  • パブリッシュ構成ファイルで<DoNotDropTables>True</DoNotDropTables>を指定する

モデルから削除されたが、まだターゲットにある列

列はオブジェクトではないため、これは少しトリッキーであり、この特定の状況を無視する特定の配置オプションはありません。ここに私が言える限りの選択肢があります:

  1. テーブルを完全に無視します。次の方法でこれを行うことができます。

    • [詳細な展開設定]([プロジェクトのプロパティ]の[デバッグ]タブにある[詳細...]ボタン)に移動し、[無視]タブに移動して、[テーブルを除外]オプションを有効にします([除外されたオブジェクトタイプ」のスクロール可能なリスト)。
    • /p:ExcludeObjectType=Tablesコマンドラインオプションの使用
    • パブリッシュ構成ファイルで<ExcludeTables>True</ExcludeTables>を指定する

    ここでの欠点は、新しい列または新しいテーブルが発行されないことです。プロジェクトにデプロイメントスクリプトを追加し、それらの「ビルドアクション」(SQLスクリプトのプロパティ)を「PreDeploy」に設定することで、自分でそれらを管理できます。

  2. SSDT APIにコードを記述する手段である「デプロイメントコントリビューター」を作成して、DDLの生成方法を制御します

    これは、特にあなたの宗教が自己鞭打ちを実践している場合、非常に柔軟で強力なオプションです;-)。

    UPDATE:さらに良いことに、 Ed Elliot はブログ投稿を公開し、彼はデプロイメントコントリビューターの使用方法を詳しく説明しています: SSDT展開コントリビューター内より良く、彼が使用した例はこれを行うことです:モデルにない列のドロップを防ぎます。 最高である、サンプルコードは実際に彼の AgileSqlClub SqlPackageデプロイメントフィルターに組み込まれています) プロジェクトであり、機能は次のブログ投稿で説明されています: Deployment Contributor KeepTableColumns Filter 。また、機能が必要な機能を正確に実行しない場合、ソースコードが利用可能であり、必要な変更を加えて再コンパイルできます。

    ????

  3. スキーマの変更にSSDTを使用しないでください。コードをプッシュするために使用するだけです(ストアドプロシージャ、関数、トリガー、SQLCLRオブジェクトなど)。独自のスキーマ展開スクリプトを記述して、プロジェクトに含めることができます。それらの「ビルドアクション」を「PreDeploy」に設定することで、それらをデプロイメントスクリプトに含めることができます。

  4. ファイルa Connect Suggestion "DoNotDropColumns"またはそのようなものにオプションを追加するには:-)

10
Solomon Rutzky