我在Sybase ASE数据库中有两个触发器,在两个表的更新时触发:Docs和Trans。
触发器的定义如下所示:
For Docs:
CREATE TRIGGER dbo.Index_Change_Docs
ON dbo.docs
FOR INSERT,UPDATE AS
IF UPDATE(DOCTYPE) OR UPDATE(BATCH_NO) OR UPDATE(SCANDATE) OR
UPDATE(PERIOD_START_DATE) OR UPDATE(PERIOD_END_DATE)
OR UPDATE(DISPATCH_ID) OR UPDATE(DISPATCH_NAME) OR UPDATE(CHECKNUM) OR
UPDATE(CHECKAMT)
BEGIN
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT Inserted.DOCID, GETDATE(), "N" FROM Inserted
END
对于Trans:
CREATE TRIGGER dbo.Index_Change_Trans
ON dbo.Trans
FOR INSERT,UPDATE AS
IF UPDATE(TRANSNUM) OR UPDATE(CONTRACT) OR UPDATE(FRANCHISE) OR UPDATE(SSN) OR
UPDATE(STATE_CODE) OR UPDATE(TRANSTYPE)
OR UPDATE(AGENCYNUM) OR UPDATE(LOCKBOXBATCHNUM) OR UPDATE(PRODUCTCODE)
BEGIN
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT DOCID, GETDATE(), "N" FROM DOCS
WHERE Transnum = (SELECT Inserted.TransNum from Inserted)
END
看起来这些触发器的行为是不同的,具体取决于对这些表的更新的方式。
在一种情况下,这些表通过两个存储过程(Insert_Docs_SP和Insert_Trans_SP)进行更新。当发生这种情况时,每个触发器都会触发一次(一次用于Docs,一次用于Trans),一切都按预期工作。
在另一种情况下,这些表在具有两个数据库更新的Sybase事务中更新。这里,第一次更新是通过调用应用程序中的内联SQL完成的(它触发Trans触发器。)第二次更新是通过存储过程完成的 - Insert_Docs_SP,与其他情况相同 - 不会触发触发器。< / p>
或许有一些关于如何处理交易的事情,我不理解?
答案 0 :(得分:0)
在两个触发器中,只有在更新某些列时,触发器才会插入docid_sync表。您确定存储过程正在更新触发器中的一个列吗?如果是触发器调用的递归更新,也不会调用触发器,但这似乎不是这种情况。
另一种可能性是,如果调用事务使用set triggers off命令禁用了触发器。我首先要确保存储过程正在更新触发器检查中的一个列。
另一个问题:在错误情况下的内联SQL和存储过程中,同一行是否被更新两次,还是更新了两个不同的行?
答案 1 :(得分:0)
我找到了答案 - 它按执行顺序排列。我认为其中一个触发器没有被触发 - 在这种情况下是Index_Change_Trans触发器 - 但实际上它是。但是,我没有看到结果,因为此触发器依赖于Docs表中的条目。
INSERT INTO
DOCID_SYNC (IS_DOC_ID, CRTN_DT, SYNC_STATUS_CDE)
SELECT DOCID, GETDATE(), "N" FROM DOCS
WHERE Transnum = (SELECT Inserted.TransNum from Inserted)
因此,如果Trans表在Docs表之前更新,则Trans触发器的运行不会在Docid_Sync表中显示更新 - 因为此时Docs表中没有相应的Transnum条目值。在这些情况下,Docid_Sync表只有一个条目,即文档触发器的结果。
在其他情况下,首先更新Docs表,然后更新Trans表。在这些情况下,Docid_Sync表有两个条目 - 一个是Docs触发器的结果,另一个是Trans触发器的结果。