アイテムテーブル&アイテムテーブルのすべての変更を記録するItems_Logテーブルがあります。TRIGGERのROLLBACKによりメッセージが表示される3609
CREATE TABLE [dbo].[Items] (
[item_id] [int] IDENTITY(1,1) NOT NULL,
[item_name] [varchar](50) NOT NULL,
[item_desc] [varchar](250) NULL,
[modified_by_id] [int] NOT NULL,
[modified_date] [datetime] NOT NULL
)
CREATE TABLE [dbo].[Items_Log] (
[item_log_id] [int] IDENTITY(1,1) NOT NULL,
[item_id] [int] NOT NULL,
[item_name] [varchar](50) NOT NULL,
[item_desc] [varchar](250) NULL,
[modified_by_id] [int] NOT NULL,
[modified_date] [datetime] NOT NULL
)
アイテムテーブルの更新は、SPROCで実行されます。それはどのような方法で更新されますときに、古いデータをログに記録するアイテムテーブル上のトリガがあり
CREATE PROCEDURE [dbo].[pUpdateItem]
@ItemID INT,
@Name VARCHAR(100),
@ByID INT
AS
UPDATE [Items] SET
item_name = @Name,
--modified_by_id = @ByID,
modified_date = GETDATE()
WHERE item_id = @ItemID;
GO
(後述のように[modified_by_id]意図的に、コメントアウト)。 RAISERRORが呼び出されるように
ALTER TRIGGER [dbo].[tItemsUpdate]
ON [dbo].[Items]
AFTER UPDATE
AS
BEGIN
SET NOCOUNT ON;
IF (UPDATE(modified_by_id) AND UPDATE(modified_date))
BEGIN
INSERT INTO [Items_Log]
SELECT * FROM Deleted
END
ELSE
BEGIN
RAISERROR ('[modified_by_id] and [modified_date] must be updated.', 16, 1)
ROLLBACK TRANSACTION
END
END
トリガーをテストするには、[modified_by_id]コメントアウトされています。
Msg 50000, Level 18, State 1, Procedure tItemsUpdate, Line 15
[modified_by_id] and [modified_date] must be updated.
Msg 3609, Level 16, State 1, Procedure pUpdateItem, Line 5
The transaction ended in the trigger. The batch has been aborted.
第1のエラーは明らかに私が見たいエラーであり、トランザクションは正しくロールバックされます。しかし、私は本当に、このようなユーザーのために表示されるので、2番目のエラーをスローせずに終了したい。
私は、他の場所で見てきた提案に基づいて、トランザクションとロールバックの正式な宣言と共に、SPROCでTry ... Catchを実行しようとしました(そして、ロールバックをトリガーから取り除く)。これはSPROCのように見えました。
BEGIN TRY
BEGIN TRANSACTION
UPDATE [Items] SET
item_name = @Name,
--modified_by_id = @ByID,
modified_date = GETDATE()
WHERE item_id = @ItemID;
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH
ここで更新は行われませんが、エラーメッセージは表示されません。 RAISERRORのものさえありません。
私は単純に "Msg 3609"を押せばいいと思う。そうすれば、すべてが私が望むやり方で動作させることができます。しかし、この時点で、私はほとんどすべての解決策を取ります。
誰もがこれを手伝ってくれますか?
[OK]を、私は、エラー情報をそのように取得していますが、今では戻って私のクラスにエラーを投げていません。キャプチャされた値でRAISERRORをやり直すことができたと思いますか? – Bob
はい、おそらくいくつかの情報を追加すると、新しいエラーが発生する可能性があります。 – Serg
うん、私はほぼすべてのSPROCをこの操作を行う必要がある場合、少しかさばることになるだろうが、これは私が今持っているものは基本的である: はCATCH DECLARE @ErrorSeverity INT' が '' @ErrorState INT' をDECLARE BEGIN @ErrorMessage VARCHAR(100) ' SET @ErrorSeverity = ERROR_SEVERITY() SET @ErrorState = ERROR_STATE() SET @ErrorMessage = ERROR_MESSAGE() ROLLBACKトランザクションを宣言します。 RAISERROR(@ ErrorMessage、@ErrorSeverity、@ErrorState); END CATCH ' – Bob