2012-01-25 15 views
2

関連するテーブルに挿入する方法を見てから何年も経ちました。私はいつもストアドプロシージャを書くことでそれをやったことがありますが、過去8年ほどで、よりよい方法があるかどうかを確かめようとはしませんでした。私はおそらく結合された挿入物の方が良い方法があるのだろうかと思っていた。関連テーブルに一度に挿入する方が良いですか?

だから私はこれらの2つのテーブルを持っていると言う。

[ユーザー]

UserID (Identity, Primary Key) 
Name 
UserExtendedPropertyID (Foreign Key, Indexed) 

[UserExtendedProperty]

UserExtendedPropertyID (Identity, Primary Key) 
Address 
Phone 

は、私は、新しいユーザーを挿入したかったと言います。私は伝統的のような何かをするだろう、ストアドプロシージャを記述します。私が参加し、インサートをやらせるだろう1つのクエリがなければならないよう

insert into UserExtendedPropertyID (Address, Phone) values('123 Fake St.', '867-5309') 
set @myidentity = select @@identity 
insert into Users (Name, UserExtendedPoerpertyID) values('John Doe', @myidentity) 

は常に感じたが、私はそのようなことを発見したことはありません。

+0

残念ながら、レコードがテーブル2に挿入される準備ができたら、外部キー制約に基づいて、テーブル1の項目に対応する値を持たなければならない。 –

答えて

0

SQL Serverのバージョンが2005+である場合は、は、その後、次の操作を実行しようと、これらのテーブル間のFKey制約を強制しない場合は、それを除くを行うための方法はありません。

insert into UserExtendedProperty (Address, Phone) 
OUTPUT 
    'John Doe', 
    INSERTED.UserExtendedPropertyId 
INTO Users(NAME, UserExtendedPropertyId) 
values('123 Fake St.', '867-5309') 
は、

しかし、なぜあなたは原子性のために、このような振る舞いをしたいですか?

+0

非常に良い。しかし、あなたが言ったように、fkの制約を無効にしなければ、どんなメリットも打ち消されます。おそらく、次のSQL Serverリリースでは、fk制約が有効になっている間にこれを行うことができます。彼らはこの機能を "コミットされていない外部キーの制約のない挿入"と呼ぶことができます。結局のところ、それは失敗する妥当性チェックだけです。この場合、有効性がすでに分かっているため、検証は必要ありませんでした。 – Lucidmike78

+0

私が言ったように、FKを有効にする方法はありません –

0

私はOleg Dokの回答に同意します。それに加えて、私はあなたの既存のスクリプトに潜在的な問題を指摘したいと思います。

投稿者:

それは、

OPTION (MAXDOP 1) 

は、上記のリンクから、このhttp://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=328811

エキスを確認してください含めず@@アイデンティティまたはSCOPE_IDENTITY()を使用することはお勧めできませんMicrosoftの2008年3月18日午後10時10分

Dave、あなたの非常に詳細で勤勉なレポートのおかげで、 に問題が見つかりました。 はい、それはバグです。パラレルクエリプランが @@ IDENTITYで生成され、SCOPE_IDENTITY()が更新されていない場合は、 が一貫しており、依存することはできません。私は今の にあなたを提供することができますいくつかの回避策:

  1. 使用MAX_DOP = 1あなたは既に使用されているよう。これは、クエリのSELECT部分​​のパフォーマンスを低下させる可能性があります。
  2. SELECTの部分の値を変数のセット(または単一のテーブル変数)に読み込んで、MAX_DOP = 1のターゲットテーブルに挿入します。 INSERTプランは並列化されないため、 セマンティックが得られますが、実際に必要な場合は、SELECTがパフォーマンスを達成するために並行して実行されます。
  3. INSERTのOUTPUT節を使用して、探していた値を取得します(下の例を参照)。実際、すべてのケースで@@ IDENTITYではなくOUTPUTを使用することを強くお勧めします。 アイデンティティとタイムスタンプを読み取る方法は、ちょうど です。
  4. オートスタンドの変更は適切な回避策ではありません。それはしばらくの間問題を隠しているかもしれませんが、並列計画は最終的に生成されます。
  5. sp_configure 'max degree of parallelism'オプションを使用して、サーバー全体のシリアル・プランを強制します。
+0

これを指摘してくれてありがとう。私は、この大きさの不具合がそこにあったということを知らなかったし、MSはまだそれについて何もしていない。それはちょっと気違いです。これからOUTPUTを使用します。とても有難い! – Lucidmike78

関連する問題