4

わかりました、質問が明確ではなかったと思います。ここで、これを別の方法で書き直します。

2 つのテーブルを作成するとします。

  • table1(c1 int PRIMARY KEY)

  • table2(table1c11 int)

table1table2 ieの間には関係があります。table1.c1=table2.table1c11

そして、次のステートメントをtable1andで実行しますtable2

insert into table1(c1)
values('a'),('b'),('c'),('d'),('e')

insert into table2(table1c11)
values('a'),('a'),('b'),('d')

そして今、私が達成したいのは、対応するデータの値を更新すると、c1自動的table1table2変更されるということです。このためには、table1table2の関係で制約を作成し、 を適用する必要がありますCASCADE UPDATE

そのため、後で新しい SQL 更新ステートメントを適用しますtable1

Update table1 set c1=c1+'updated'

次に、 のデータtable2も変更されます。しかし、 を介して同じ機能を実現したい場合はINSTEAD OF UPDATE TRIGGER、 update トリガーの代わりに を記述する必要があり、その中に 2 つのマジック テーブルINSERTEDとを使用してそれを処理する必要がありDELETEDます。

しかし、要点は、この場合、1 つの列しか存在せずtable1、同じ列を更新しているので、挿入された行と削除された行をどのようにマップできるかということです。CASCADing を使用すると、SQL Server でも同じことが行われます。

そのため、テーブルの主キー データが変更された場合に、SQL Server がバッチ更新をどのように処理するかという疑問が生じます。

4

1 に答える 1

12

そのため、テーブルの主キー データが変更された場合に、SQL Server がバッチ更新をどのように処理するかという疑問が生じます。

SQL Server は、両方のテーブルを更新する update ステートメントのクエリ プランを作成します。

テーブルを作成します。

create table T1
(
  T1ID int primary key
);

create table T2
(
  T2ID int primary key, 
  T1ID int references T1(T1ID) on update cascade
)

いくつかのデータを追加します:

insert into T1 values(1), (2)
insert into T2 values(1, 1), (2, 1), (3, 2)

の主キーを更新T1:

update T1
set T1.T1ID = 3
where T1.T1ID = 1

更新のクエリ プランは次のようになります。

更新カスケードでの更新のクエリ プラン

T1この計画には、 用と用の 2 つの Clustered Index Update ステップがありますT2

更新 1:

複数の主キー値が更新された場合、SQL Server は更新する行をどのように追跡しますか?

update T1
set T1.T1ID = T1.T1ID + 100

更新カスケードで複数の行を使用した更新のクエリ プラン

一番上のブランチ ( の更新) の Eager Spool は、計算れたT1古いものと新しいものを、下のブランチ ( の更新) で使用される一時テーブルに保存します。下のブランチのハッシュ マッチは、テーブル スプールを古いブランチに結合しています。の更新に対するハッシュ マッチからの出力は、テーブル スプールから計算された新しいクラスター化インデックス スキャンからのものです。T1IDT1ID (Expr1013)T2T2T1IDT2T2IDT2T1ID (Expr1013)

更新 2:

cascade updateを aに置き換える必要がある場合は、トリガーでとテーブルinstead of triggerを結合する方法が必要です。これは、 の代理キーを使用して実行できます。inserteddeletedT1

テーブル:

create table T1
(
  T1ID int primary key,
  ID int identity unique
);

create table T2
(
  T2ID int primary key, 
  T1ID int references T1(T1ID)
);

トリガーは次のようになります。

create trigger tr_T1 on T1 instead of update as

insert into T1(T1ID)
select T1ID
from inserted;

update T2
set T1ID = I.T1ID
from inserted as I
  inner join deleted as D
    on I.ID = D.ID
where D.T1ID = T2.T1ID;

delete from T1
where T1ID in (
              select T1ID
              from deleted
              );

SQL フィドル

于 2013-02-25T10:52:18.183 に答える