2012-03-27 7 views
0

私はテーブルの数にほぼ同じトリガの数(およびデータベースの数)を変更する必要が目標はローカルで始まるエンドは(単一のトランザクションで複数のトリガーを変更すること)宣言し

スコープ。 したがって、1つの大きなスクリプトを作成し、1つの成功または失敗のトランザクションですべての変更を実行することはできません。自分でALTER TRIGGER文の各実行

私の最初の試み(それが動作しません)

---First alter trigger 
ALTER TRIGGER [dbo].[trg_UserGarbleValue] ON [dbo].[users] 
FOR INSERT 
AS 
Begin 
    DECLARE @GarbleValue NVARCHAR(200) 
    DECLARE @NewID NVARCHAR(20) 

    SET @NewID = (SELECT TOP 1 usr_id FROM users ORDER BY usr_id DESC) 

    SET @GarbleValue = dbo.fn_GetRandomString(4) + @NewID + dbo.fn_GetRandomString(4) 

    UPDATE users SET usr_garble_value = @GarbleValue WHERE usr_id = @NewID 
End 
Go 

--Subsequent alter trigger (there would be many more in the real-world usage) 
ALTER TRIGGER [dbo].[trg_SegmentGarbleValue] ON [dbo].[segment] 
FOR INSERT 
AS 
Begin 
    DECLARE @GarbleValue NVARCHAR(200) 
    DECLARE @NewID NVARCHAR(20) 

    SET @NewID = (SELECT TOP 1 seg_id FROM segment ORDER BY seg_id DESC) 

    SET @GarbleValue = dbo.fn_GetRandomString(4) + @NewID + dbo.fn_GetRandomString(4) 

    UPDATE segment SET seg_garble_value = @GarbleValue WHERE seg_id = @NewID 
End 
Go 

が正常に動作します。しかし、それらの両方が同じトランザクションで実行されると、変数名がすでに存在するため、2番目のalterでクラッシュが宣言されます。

どうすればよいですか? begin-endスコープ内でローカルに変数を宣言する方法はありますか、それとも完全に再考する必要はありますか?

は(私は新しいレコードをフェッチするための「トップ1は」おそらく非常に巧妙ではないことを承知しているが、それは別の問題です)私はあなたが混乱しGO(バッチ区切り)との取引をしたと思う

答えて

0

。 - トリガーはの文ごとに一度実行さ

BEGIN TRANSACTION 
GO 
ALTER TRIGGER [dbo].[trg_UserGarbleValue] ON [dbo].[users] 
FOR INSERT 
AS 
---Etc 
Go 
ALTER TRIGGER [dbo].[trg_SegmentGarbleValue] ON [dbo].[segment] 
FOR INSERT 
AS 
---Etc 
Go 
COMMIT 
メモ程度TOP 1については

が、それはあなたが考えているよりも悪いことだ:それはバッチ区切りがまだ存在している提供、変数名を再宣言されて文句を言うべきではありませんは、1行に1回ではなく、複数の行が挿入されたことに応答して実行されている可能性があります。そして、幸いなことに、擬似テーブル(insertedと呼ばれています)があります。このテーブルにはトリガを発生させた行が含まれています。ベーステーブルの行を検索する必要はありません。

+0

ありがとうございます。私は2つのステートメントの間にGo(;)がありませんでした。 –

+0

トップ1について:あなたは正しいですが、データを書き込むシステムは常に別々のインサートを使用するため、現在は問題にはなりません(ただし、とにかく変更すると思いますので、 。 –

関連する問題