- PR -

SQLServer トリガを仕掛けたところテーブル更新ができない

投稿者投稿内容
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-09 12:11
今回、TABLE_Aに対して、INSERTトリガ、UPDATEトリガ、DELETEトリガを
仕掛け、TABLE_Bにレコードを作製する、トリガを作成しました。

普通にテストでは動いていたのですが
いざ、本番環境に入れたところ、
TABLE_Aの登録エラーが発生しました。

それぞれのトリガは更新後に走る処理のはずなのに
なぜ起こったのでしょうか?
もし考えられる原因・対処法があれば
申し訳ありませんがご教授ください。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-09 12:15
エラーの内容と具体的なトリガを教えてください
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-11-09 12:24
引用:
それぞれのトリガは更新後に走る処理のはずなのに


何か勘違いしていませんか? AFTER トリガであっても、トリガ内の処理とトリガ起動元の処理は同一トランザクションになります。なので、トリガ内の処理でエラーが発生すると、起動元の処理も失敗しロールバックされます。

原因は知りませんけど、単純に TABLE_B の更新に失敗しているのでしょう。
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-09 14:28
トリガはこのような感じです。
ということは、この中にエラーがあるということでしょうか…


GO
/****** オブジェクト: Trigger [Trig_Upd_TABLE_A] スクリプト日付: 10/11/2007 15:03:01 ******/
IF EXISTS (SELECT * FROM sys.triggers WHERE object_id = OBJECT_ID(N'[db_owner].[Trig_Upd_TABLE_A]'))
BEGIN
DROP TRIGGER [db_owner].[Trig_Upd_TABLE_A]
END

GO

CREATE TRIGGER [db_owner].[Trig_Upd_TABLE_A]
ON [db_owner].[Tbl_TABLE_A]
AFTER UPDATE
AS

DECLARE @INS_DELETEFLAG VARCHAR(1)
DECLARE @INS_COLUM_A Int
DECLARE @INS_COLUM_B VARCHAR(5)
DECLARE @INS_COLUM_C VARCHAR(3)
DECLARE @INS_COLUM_D Int
DECLARE @INS_COLUM_E Int
DECLARE @INS_COLUM_F int
DECLARE @DEL_DELETEFLAG VARCHAR(1)
DECLARE @DEL_COLUM_A Int
DECLARE @DEL_COLUM_B VARCHAR(5)
DECLARE @DEL_COLUM_C VARCHAR(3)
DECLARE @DEL_COLUM_D Int
DECLARE @DEL_COLUM_E Int
DECLARE @DEL_COLUM_F int
DECLARE @DEL_COLUM_G VARCHAR(1)

DECLARE @DELETED_INS_FLAG Int
DECLARE @INSERTED_INS_FLAG Int
DECLARE @DEL_COLUM_F VARCHAR(10)
DECLARE @INS_COLUM_F VARCHAR(10)


SELECT @DEL_DELETEFLAG=[Deleted].DeleteFlag,
@DEL_COLUM_A=[Deleted].COLUM_A,
@DEL_COLUM_B=[Deleted].COLUM_B,
@DEL_COLUM_C=[Deleted].COLUM_C,
@DEL_COLUM_D=[Deleted].COLUM_D,
@DEL_COLUM_E=[Deleted].COLUM_E,
@DEL_COLUM_F=[Deleted].COLUM_F,
@DEL_COLUM_G=[Deleted].COLUM_G,
@DEL_COLUM_F=[Deleted].COLUM_F
FROM [Deleted]

SELECT @INS_DELETEFLAG=[Inserted].DeleteFlag,
@INS_COLUM_A=[Inserted].COLUM_A,
@INS_COLUM_B=[Inserted].COLUM_B,
@INS_COLUM_C=[Inserted].COLUM_C,
@INS_COLUM_D=[Inserted].COLUM_D,
@INS_COLUM_E=[Inserted].COLUM_E,
@INS_COLUM_F=[Inserted].COLUM_F,
@INS_COLUM_F=[Inserted].COLUM_F
FROM [Inserted]

IF NOT EXISTS
(SELECT * FROM Tbl_TABLE_B
WHERE COLUM_H=@INS_COLUM_A
AND COLUM_B=@INS_COLUM_B
AND COLUM_C=@INS_COLUM_C
AND COLUM_D=@INS_COLUM_D
AND COLUM_E=@INS_COLUM_E
AND UpdateHiduke IS NULL
)
BEGIN
SELECT
@INSERTED_INS_FLAG=0
END

IF NOT EXISTS
(SELECT * FROM Tbl_TABLE_B
WHERE COLUM_H=@DEL_COLUM_A
AND COLUM_B=@DEL_COLUM_B
AND COLUM_C=@DEL_COLUM_C
AND COLUM_D=@DEL_COLUM_D
AND COLUM_E=@DEL_COLUM_E
AND UpdateHiduke IS NULL
)
BEGIN
SELECT
@DELETED_INS_FLAG=0
END



IF @DEL_COLUM_G<>'2'
BEGIN

IF @DEL_COLUM_F<>'6' AND @INS_COLUM_F='6'
BEGIN

IF @DELETED_INS_FLAG='0'
BEGIN
INSERT INTO Tbl_TABLE_B
SELECT
NEWID(),
[Deleted].COLUM_A,
[Deleted].COLUM_B,
[Deleted].COLUM_C,
[Deleted].COLUM_D,
[Deleted].COLUM_E,
REPLACE(CONVERT(VARCHAR,GetDate(),120), '-', '/'),
NULL
FROM [Inserted],[Deleted]
END
END

-- 削除フラグ更新時の処理
ELSE IF @DEL_DELETEFLAG=0 and @INS_DELETEFLAG=1
BEGIN
IF @DELETED_INS_FLAG='0'
BEGIN
INSERT INTO Tbl_TABLE_B
SELECT
NEWID(),
[Deleted].COLUM_A,
[Deleted].COLUM_B,
[Deleted].COLUM_C,
[Deleted].COLUM_D,
[Deleted].COLUM_E,
REPLACE(CONVERT(VARCHAR,GetDate(),120), '-', '/'),
NULL
FROM [Inserted],[Deleted]
END
END

ELSE IF @INS_DELETEFLAG=0
BEGIN
IF @DEL_COLUM_A=@INS_COLUM_A
AND @DEL_COLUM_B=@INS_COLUM_B
AND @DEL_COLUM_C=@INS_COLUM_C
AND @DEL_COLUM_D=@INS_COLUM_D
AND @DEL_COLUM_E=@INS_COLUM_E
AND @DEL_COLUM_F=@INS_COLUM_F
BEGIN
IF @INSERTED_INS_FLAG='0'
BEGIN
INSERT INTO Tbl_TABLE_B
SELECT
NEWID(),
[Inserted].COLUM_A,
[Inserted].COLUM_B,
[Inserted].COLUM_C,
[Inserted].COLUM_D,
[Inserted].COLUM_E,
REPLACE(CONVERT(VARCHAR,GetDate(),120), '-', '/'),
NULL
FROM [Inserted],[Deleted]
END
END

ELSE IF @DEL_COLUM_A<>@INS_COLUM_A
OR @DEL_COLUM_B<>@INS_COLUM_B
OR @DEL_COLUM_C<>@INS_COLUM_C
OR @DEL_COLUM_D<>@INS_COLUM_D
OR @DEL_COLUM_E<>@INS_COLUM_E
OR @DEL_COLUM_F<>@INS_COLUM_F

BEGIN
IF @DELETED_INS_FLAG='0'
BEGIN
INSERT INTO Tbl_TABLE_B
SELECT
NEWID(),
[Deleted].COLUM_A,
[Deleted].COLUM_B,
[Deleted].COLUM_C,
[Deleted].COLUM_D,
[Deleted].COLUM_E,
REPLACE(CONVERT(VARCHAR,GetDate(),120), '-', '/'),
NULL
FROM [Deleted]
END
IF @INSERTED_INS_FLAG='0'
BEGIN
INSERT INTO Tbl_TABLE_B
SELECT
NEWID(),
[Inserted].COLUM_A,
[Inserted].COLUM_B,
[Inserted].COLUM_C,
[Inserted].COLUM_D,
[Inserted].COLUM_E,
REPLACE(CONVERT(VARCHAR,GetDate(),120), '-', '/'),
NULL FROM [Inserted]
END
END
END
END

Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-09 15:55
デッドロックしたのかもしれませんね。
TABLE_B、TABLE_Aの順番でアクセスしている機能がないかチェックしてみてください。
ハチャ
会議室デビュー日: 2007/10/01
投稿数: 11
投稿日時: 2007-11-09 16:00
返信ありがとうございます。

TableB⇒TableAの順番の処理はありません。
今回のTableAからTableBへの更新用にTableBを作成したため
1方向だけになります。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2007-11-09 16:05
ところでエラー内容は結局なんだったのでしょうか?
未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2007-11-09 16:10
引用:

FROM [Inserted],[Deleted]


ひどい作りですね。TableA は 1行ずつしか更新しないという前提ですか? TableA を 1度に複数行更新すると inserted テーブル、deleted テーブルには複数行入ってきますよ。その直積を TableB に入れようとするわけだから、TableB にプライマリーキーが設定されていれば簡単に一意制約違反が発生するんじゃないかな。

スキルアップ/キャリアアップ(JOB@IT)