DTSインポート/エクスポートウィザードを使用してデータをインポートするときにFK制約を処理するにはどうすればよいですか?


16

SQL Serverのインポートおよびエクスポートウィザードを使用して、運用データベースから開発データベースにデータをコピーしようとしていますが、「INSERTステートメントがFOREIGN KEY制約と競合しています」というエラーで失敗します。 FK制約の場合、ドロップ制約を追加する/ constratスクリプトを追加することなく、これに対処する簡単な方法はありますか?

編集:私はちょうど私が実行しているものであるSQL ServerのWeb版では、DTSはあなたがパッケージを保存することはできませんことがわかりました。

回答:


28

SQLTeam.comでこのソリューションが提供されました。

使用する:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

次に、データをインポートします

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

その方法を使用して、すべてのデータを問題なくインポートできました。


1
sp_msforeachtable(およびsp_MSForEachDb)は文書化されておらず、サポートされていません。あなたはそれを使用するべきではありません/避けるべきです。テーブルをスキップするかもしれません!! @AaronBertrandからのこの投稿を参照してください-> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/…およびこの接続項目-(MSは修正しないことを示すMS)-> connect.microsoft.com/SQLServer /フィードバック/詳細/ 264677 / ...
キン・シャー

データエクスポートのFK制約を回避しようとして頭を痛めつけた後、私にとって完璧に働きました。
レビニンジャ

Azure SQL V12で実行すると、「ストアドプロシージャ 'sp_msforeachtable'が見つかりませんでした」というエラーが表示されます。

とにかく動作しません:/
ダグラスガスケル

あなたは命の恩人です
チャヒン・バクル

5

私が制御しなかったサーバーから、マシン上にデータベースの正確なコピーを作成しました。

私はシュマックですが、これは私がやったことです

  1. ソース管理にあるスクリプトからDBを作成しました(ヒント、ヒント!)スクリプトがない場合は、Tasksオプションを使用して既存のDBからいつでも生成できます。

  2. 作成時にYourDBにデータが自動挿入された場合、を実行しDELETE FROM YourDB.dbo.tblYourTableます。

    • 外部キーが存在する場合、データを切り捨てることはできないため、を使用する必要がありますDELETE
  3. 宛先サーバーでこれを実行します。 USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. YourDBを右クリックしますObject Explorer。クリックTasks->Import Data...

  5. ウィザードの最初のいくつかの画面は自明です。

  6. Select Source Table and Viewsウィザードの画面で、コピーするすべてのテーブルの横にあるチェックボックスをクリックします。

  7. その画面の各行(テーブル)について、クリックして強調表示し、をクリックしますEdit Mappings

  8. 行(テーブル)ごとに、クリック/チェックしてAppend rows to the destination tableをクリックしますEnable identity insert

    • クリックDelete rows in destination tableするとDELETEコマンドが発行されないため失敗TRUNCATEしますTRUNCATENOCHECK CONSTRAINT、以前のバージョンによって管理されていないため、外部キーと競合するコマンドが発行されます。
  9. ウィザードの残りをクリックしてクリックしますFinish

  10. 以下のためのウォッチエラー。警告はおそらく無視しても問題ありません。

    • エラーがある場合は、Reportボタンをクリックしてレポートを表示します。試してみていたものをSUSS SuccessErrorStopped。おそらく、そのレポートのどこかに埋もれているエラーの根本原因を修正する必要があります。次に、おそらくを実行する必要がありますDELETE FROM YourDB.dbo.theErrorTable。インポートウィザードの[戻る]ボタンをクリックし、すべてのテーブルのチェックを外しますSuccess。広告を無限に繰り返します。
  11. 宛先サーバーでこれを実行します。 USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • エラーがある場合は... ...わかりませんが、修正してもう一度やり直してください!
  12. わーい!:)

SEネットワークでこの質問とこれに似た質問に答えてくれたすべての人に感謝します。


あなたは命の恩人だ
トムGullen

1
本当にありがとうございました。破損したドライブにバックアップがあり、DBをどこにもコピーできませんでした(I / Oエラー)。この方法で一度にいくつかのテーブルにデータをインポートすると、99%のデータを回復できました。
トムガレン

1
あなたが揺れます!私を助けた別のコマンド:EXEC sp_msforeachtable 'delete from?'; エラーが発生した場合は、すべてを削除してください。sp_msforeachtableスクリプトはここにあるgist.githubusercontent.com/metaskills/893599/raw/...
Sanchitos

4

インポートウィザードでは、最初に行を削除できます。IDフィールドがある場合は、次のようにIDの挿入を有効にできます。

ここに画像の説明を入力してください

チェック制約を無効にする場合は、ウィザードでパッケージを保存するよう求められたら、パッケージを保存してから接続マネージャーを次のように編集します。

ここに画像の説明を入力してください

注:外部キーが定義されている場合、テーブルを切り捨てることはできません。


3

制約を削除しないでください。

ウィザードで作成したSSISパッケージを保存してから、BIDS / SSDTで編集する必要があります。パッケージを編集すると、テーブルの処理順序を制御できるため、親テーブルを処理し、すべての親テーブルが完了したら子テーブルを処理できます。


3
それは実際には効率的でもありません。パッケージを変更してすべてが正しい順序になっていることを確認するのに今すぐ1時間近くかかります。これは、DBが成長するたびに面倒になり、毎回行う必要があります。これを行う簡単な方法が必要です。

1

このような問題は、SQLサーバーを作成する人々が実際に製品を使用したことがないことを示しています。これは非常に目立たないため、他のDBが行うように、この作業を行うために克服しなければならなかった約30の他の厄介な問題のリストがあります。最初にこれを行うには粗末なウィザードが必要であるという事実を含む[このウィザードが同じDBの同じテーブルに接続して列挙するのを待つ時間があった場合...素敵な休暇を過ごす時間があるだろう])。

私はとても怠け者で、タイプしたくない EXEC sp_msforeachtable ...これを行うたびに2回。私の回避策は、実稼働サーバーに制約を残し、それらを開発サーバーから削除することです。これはエラーを防ぎますが、この方法にはいくつかの非常に大きな副作用があります。まず、完全なバックアップをdevサーバーに復元することはできなくなります(すべてを完全に削除しても問題ない限り)。第二に、これは、データのコンシューマーがこれらの制約を強制する(またはそれらを気にしない)と確信している場合に最もよく機能します。私の場合、消費者(ウェブサイト)は1人だけなので、これらの制約をサイトコードにも組み込みました(つまり、ユーザーレコードを削除する前に、そのユーザーのすべての電話レコードを最初に削除します)。はい、これは、本質的に制約の必要性を本質的に無効にし、行う必要がある作業を2倍にしますが、DBMSベースの制約の有無にかかわらずコードが機能することを検証する機会も与えます緊急時対応計画としてのみ)。これを私の設計の欠陥と呼ぶこともできますが、私はむしろ欠陥のあるDBMSの回避策と呼びます。とにかく、独自の設計に対応できないため、MSSQL内からよりも他の場所でこれを行う方が迅速かつ簡単です。


0

運用サーバーからのバックアップと復元は重要なデータであるため、実行できないと思います。適切な権利がなければ、本当に複雑になります。ただし、db backup n restore権限がある場合は実行できます。

または、すべての制約とインデックスを削除し、データがインポートまたはエクスポートされたら再度追加することをお勧めします。

正確な答えではありませんが、高速に処理されます。


感謝しますが、具体的には、ドロップ/作成制約スクリプトをスクリプト化したくないと言いました。

0

そのトピックを読んでください。それは古い投稿ですが、これを読んでいる将来の人々を助けるために私がやったことです。

私の場合、空の同一テーブルにインポートしたかった。マッピングを編集するとき<ignore>、主キーを選択します。すべてのコンテンツが自動的にうまく追加されています。

それが誰かを助けることを願って


1
主キーを無視すると、外部キーに役立ちますか?
-dezso

私の場合、実際にテーブルを複製していたので、はい。だから私は同じ主キーで終わった。したがって、私のテーブルを指している外部キーは正しいエントリにまだ対応しています。
グレッグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.