2011-01-28 8 views
3

私はいくつかのトリガーパフォーマンスの最適化を行っています。テストしたいです。私は実際のトリガーと変更されたトリガーを持っていて、私は実際のデータで古いトリガーと新しいトリガーのテストを実行し、それを比較したい。テーブルAを行ごとにA_BCKにコピーしたい。表Aには約60列と4000行があるため、トリガーは4000回実行され、パフォーマンステストに使用できます。行ごとに行をコピーする

私はカーソルについて読んだことがありますが、行ごとのコピーでカーソルと変数を使用する方法(a_bckに選択しないでください。今のよう

私の行のコピー手順は、次のようになります。

declare @actualrow varchar(15); 

DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT * FROM A 

open eoauz 
fetch next from eoauz into @actualrow 
while @@fetch_status = 0 
begin 
/* INSERT INTO A_BCK VALUES FROM @actualrow */ 
fetch next from eoauz into @actualrow 
end 
close eoauz 
deallocate eoauz 

もちろん、これは動作しません。私はvarcharの代わりに行変数のようなものが必要です。誰かが私の仕事を達成する方法を手伝いますか?

+2

なぜこの行を行単位で処理していますか? MSSQLはベースに設定されています。あなたが痛みの世界に住んでいない限り、特にトリガでは、カーソルを使用しないでください。 – codingbadger

+0

私はこの_in_私のトリガーをしないでください。私はこれを実行して、私のトリガを試してみたいです。私は実際のデータに対してトリガを実行する方法が必要です。 –

+0

'into @ actualrow'ビットを削除すると、行全体がクライアントに返されます。どうやら別のテーブルにその行を挿入する構文があるかどうかはわかりません。 –

答えて

1

サンプルテーブル

create table A(ID INT IDENTITY, a int, b int) 
create table B(ID INT, a int, b int) 
insert A select 1,2 union all select 3,4 union all select 5,6 

以下のコードのためにあなたは、各列の変数を必要としています。私はカーソルを使用し、代わりに私が欠けている、より簡単な方法があるかもしれないので、私は多くの場合、カーソルでは動作しません可能な限り

declare @id int 
select top 1 @id = id from A order by ID 
while @@ROWCOUNT > 0 begin 
    insert B select * from A where [email protected] -- one row 
    select top 1 @id = id from A where id > @id order by ID 
end 
+0

答えをありがとう。私が気にしていないのは、60列あるので、60変数を宣言しなければならないということです。さらに、私はカーソルをテストに使用するだけです。私はプロダクションDBにカーソルを持っていません。だから実際に私は生産でそれを使用するという恐れはありません;-) –

+0

@Robert - テーブル – RichardTheKiwi

+0

に戻って1つの列(キー)を使用してwhileループの代替(カーソルで動作することもあります)私は今それを試して –

4

whileループを使用しないことを好む

declare @id int, @a int, @b int 
DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT * FROM A 
open eoauz 
fetch next from eoauz into @id, @a, @b 
while @@fetch_status = 0 
begin 
INSERT B VALUES(@id, @a, @b) 
fetch next from eoauz into @id, @a, @b 
end 
close eoauz 
deallocate eoauz 

以下の例を参照してください。 ...

SELECT TOP 0 * 
INTO #t 
FROM master..spt_values /*Create an empty table of correct schema*/ 

DECLARE eoauz CURSOR FAST_FORWARD FOR 
    SELECT * 
    FROM master..spt_values 

OPEN eoauz 

INSERT INTO #t 
EXEC ('fetch next from eoauz') 

WHILE @@FETCH_STATUS = 0 
    INSERT INTO #t 
    EXEC ('fetch next from eoauz') 

CLOSE eoauz 

DEALLOCATE eoauz 

SELECT * 
FROM #t 

DROP TABLE #t 
+0

残念。私は投票してしまったので、もうこの回答をアップヴォートできません。私がしたことは、私がそれを上書きしてすぐに、方法が機能するかどうか最初に確認するために投票をすぐに呼び出すことです。それは持っています。今私はそれをもう一度upvoteしようとしているが、回答が編集されるまで私の投票がロックされているということを続けている。それは本当に頑固ですか?あなたの答えは、ほとんど無意味な 'select * from#t'を最後に追加しない限り、実質的に変更する必要はないようです(あなたの例は単なるテストにすぎません)。そうでなければ、それは私の考えです。したがって、期限が切れているupvoteが保留中です。 –

+0

@Andriy - ありがとう!私は提案された変更を行った。 –

+0

+1があります。 (*脇に*)大した場合の投票ブロック事件が問題であるのか、それとも機能であるのだろう... –

0

あなたのカーソル変数にテーブルの主キーを選択します。

declare @pk varchar(15); 

DECLARE eoauz CURSOR FAST_FORWARD FOR SELECT PK FROM A 

open eoauz 
fetch next from eoauz into pk 
while @@fetch_status = 0 
begin 
INSERT INTO A_BCK select * from A where PK = @pk 
fetch next from eoauz into pk 
end 
close eoauz 
deallocate eoauz 

私はこの方法を理解し、読みやすいものに大きな利点を持っていると思う:これは一意にあなたがして簡単に選択することができ、単一の行を識別します。