1

「削除後」とは、削除が行われるまでトリガーが起動されないことを意味すると思いましたが、これが私の状況です...

C# でトリガーを削除した後、3 つのほぼ同一の SQL CLR を作成しました。これは約 1 か月間、美しく機能しました。自動削除ツールの実行中に、3 つのうちの 1 つが突然動作を停止しました。

動作を停止したということは、クライアント ソフトウェアを介してテーブルからレコードを削除できなかったことを意味します。トリガーを無効にすると削除が許可されましたが、再度有効にすると削除できなくなりました。

だから私の質問は、「これはどうしてですか?」ということです。それに使用されたツールがメモリを混乱させた可能性はありますか?トリガーが例外をスローしたとしても、それが AFTER delete の場合、レコードは削除されるべきではありませんか?

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

ALTER TRIGGER [sysdba].[AccountTrigger] ON [sysdba].[ACCOUNT]  AFTER  DELETE AS 
EXTERNAL NAME [SQL_IO].[SQL_IO.WriteFunctions].[AccountTrigger]
GO

CLR トリガーは、別のデータベースに対して 1 つの選択と 1 つの挿入を行います。SQL Server Mgmt Studio からのエラーがあるかどうかはまだわかりませんが、見つけ次第質問を更新します。

アップデート:

上記の同じトリガー コードを再実行すると、すべてが再び機能するようになるため、SSMS でエラーが発生した場合はどうなるかわかりません。

また、トリガーのコードのどこにもロールバックの呼び出しはありません。

4

3 に答える 3

6

after は、イベントの後に発生することを意味し、ロールバックすることができます

create table test(id int)
go


create trigger trDelete on test after delete
as

print 'i fired '
rollback

挿入する

insert test values (1)

今すぐデータを削除します

delete test

トリガーからの出力は次のとおりです

私は解雇した

メッセージ 3609、レベル 16、状態 1、行 1

トランザクションはトリガーで終了しました。バッチは中止されました。

テーブルをチェックして、何も削除されていないことを確認します

select * from test

CLR トリガーは、別のデータベースに対して 1 つの選択と 1 つの挿入を行います。SQL Server Mgmt Studio からのエラーがあるかどうかはまだわかりませんが、見つけ次第質問を更新します。

自動削除ツールの実行中に、3 つのうちの 1 つが突然動作を停止しました。

トリガーは行ごとではなくバッチ/ステートメントごとに起動します。トリガーが複数行操作用にコーディングされておらず、自動ツールがバッチ内の複数の行を削除した可能性はありますか? 「ベスト プラクティス: 複数行操作のための SQL Server トリガーのコーディング」を参照してください。

明示的なロールバックを行わずにトリガーを失敗させる例を次に示します。

alter trigger trDelete on test after delete
as

print 'i fired '
declare @id int
select @id = (select id from deleted)
GO

いくつかの行を挿入します

insert test values (1)
insert test values (2)
insert test values (3)

これを実行

delete test

メッセージ 512、レベル 16、状態 1、手順 trDelete、行 6 を起動しました

サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。

ステートメントは終了されました。

テーブルをチェック

select * from test

何も削除されませんでした

于 2010-05-05T14:46:16.067 に答える
1

トリガーで選択を行うべきではありません (結果が表示されます)。また、行っているのが挿入だけの場合は、CLR トリガーであってはなりません。CLR は通常、トリガーに含めるのは良いことではありません。t-sql で処理できない何かを実行する必要がない限り、トリガーで t-SQL コードを使用する方がはるかに優れています。これは、トリガーではおそらく悪い考えです。

ソース管理にある最後のバージョンに戻しましたか? 破損している場合は、問題が解決する可能性があります。

于 2010-05-05T14:49:09.360 に答える
1

AFTER DELETE トリガーでエラーが発生すると、トランザクションがロールバックされます。それらは削除された後ですが、変更がコミットされる前です。これに CLR トリガーを使用している特定の理由はありますか? これは、純粋な SQL トリガーがおそらくより軽量な方法で実行できるはずのことのように思えます。

于 2010-05-05T14:45:42.247 に答える