0

要件は、あるテーブルに挿入されたすべてのレコードを別のテーブルに転送することです。私はそれを行うためにトリガーを使用しました。挿入されたすべてのレコードをループして、宛先テーブルのシーケンス番号をインクリメントする必要があるため、一度に 1 つのレコードを新しいテーブルに挿入しています。ただし、挿入される行の数が増えると、このループはかなり遅くなります。これを行うより良い方法はありますか。

Declare @maxpk int, @count int, @seq int
set @maxpk=(select max(refno) from inserted )
set @count=(select count(1) from inserted)
set @seq=((select max(seq_no) from dbase.dbo.destination))

while @count>0
begin
set @seq=(select @seq+1)
insert into dbase.dbo.destination(orderno,SEQ_NO,PRODUCT_ID,qty)
select  ordernumber,@seq,productid ,quantity
from inserted where refno=@maxpk
set @count=(select @count-1)
set @maxpk=(select top 1 refno from inserted where refno<@maxpk)
end

refno はソース テーブルの主キーです。挿入されたレコードの終わりを確認して、ループ カウンターを初期化および維持する必要がないようにする方法はありますか?

挿入されたテーブルの各レコードに対してループを実行できるため、主キーの値を比較して挿入する次のレコードを見つける必要はありません。mssql 2005 の使用

4

1 に答える 1

2

これで同時実行は問題なく処理されるはずですが、設計を再検討する必要があると思います (たとえばseq_noIDENTITY列を作成すると、システムが一意の値を生成し、同時実行も処理します)。

CREATE TRIGGER dbo.SourceTrg ON dbo.Source
AFTER INSERT
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @seq INT;
    SET @seq = COALESCE((SELECT MAX(seq_no) 
      FROM dbase.dbo.Destination WITH (TABLOCKX, HOLDLOCK)), 0);

    INSERT dbase.dbo.Destination(SEQ_NO, orderno, PRODUCT_ID, qty)
      SELECT @seq + ROW_NUMBER() OVER (ORDER BY refno),
        ordernumber, productid, quantity
      FROM inserted;
END
GO
于 2012-05-15T23:39:48.327 に答える