在什么情况下 Sybase 触发器不会被调用?

发布于 2024-11-15 17:06:21 字数 1384 浏览 2 评论 0原文

我在 Sybase ASE 数据库中有几个触发器,它们在更新两个表(Docs 和 Trans)时触发。

触发器的定义如下所示:

对于 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)进行更新。发生这种情况时,每个触发器都会触发一次(文档一次,Trans 一次),一切都会按预期进行。

在另一种情况下,这些表在 Sybase 事务中通过两次数据库更新进行更新。在这里,第一次更新是通过调用应用程序中的内联 SQL 完成的(这会触发 Trans 触发器)。第二次更新是通过存储过程 - Insert_Docs_SP 完成的,与其他情况相同 - 它不会触发触发器。

也许我不理解交易的处理方式?

I have a couple of triggers in a Sybase ASE database that are fired upon updates to two tables: Docs and Trans.

The triggers are defined as shown here:

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

For 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

It appears the behavior of these triggers is different, depending on how updates to those tables are made.

In one case, these tables are updated via two stored procedures (Insert_Docs_SP and Insert_Trans_SP). When this happens, each trigger is fired once (once for Docs, one for Trans) and everything works as expected.

In another case, these tables are updated within a Sybase transaction with two database updates. Here, the first update is done via inline SQL in the calling application (which fires the Trans trigger.) The second update is done via a stored procedure - Insert_Docs_SP, the same as in the other case - which does not fire a trigger.

Perhaps there is something about how transactions are handled that I am not understanding?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

猫瑾少女 2024-11-22 17:06:21

在这两个触发器中,只有在更新某些列时触发器才会插入到 docid_sync 表中。您确定存储过程正在更新触发器中的列之一吗?如果是来自触发器调用的递归更新,则也不会调用触发器,但这里的情况似乎并非如此。

另一种可能性是调用事务使用设置触发器关闭命令禁用触发器。我首先要确保存储过程正在更新触发器检查中的列之一。

另一个问题:在错误情况下的内联 SQL 和存储过程中,同一行是否被更新两次,或者它们是否更新两个不同的行?

In both of your triggers, the trigger is only inserting into docid_sync table if certain columns are updated. Are you sure that the stored procedure is updating one of the columns in the trigger? Triggers are also not called if it is a recursive update from a trigger call, but that doesn't seem to be the case here.

The other possibility is if the calling transaction disabled the trigger with the set triggers off command. I would start with ensuring that the stored procedure is updating one of the columns in the trigger checks.

One other question: Is the same row being updated twice, in the inline SQL And stored procedure in your error case, or are they updating two different rows?

海之角 2024-11-22 17:06:21

我找到了答案——它是按执行顺序排列的。我认为其中一个触发器没有被触发 - 在本例中是 Index_Change_Trans 触发器 - 但事实上它被触发了。但是,我没有看到结果,因为此触发器依赖于文档表中的条目。

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 触发器的结果。

在其他情况下,首先更新 Docs 表,然后更新 Trans 表。在这些实例中,Docid_Sync 表有两个条目 - 一个作为 Docs 触发器的结果,另一个作为 Trans 触发器的结果。

I found the answer - it's in the order of execution. I thought one of the triggers wasn't being fired - in this case the Index_Change_Trans trigger - but in fact it was. I didn't see the results, however, because this trigger is relying on entries in the Docs table.

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)

So, in cases where the Trans table was updated before the Docs table, the run of the Trans trigger would not show an update in the Docid_Sync table - since at this point there were no entries in the Docs table with the appropriate Transnum value. In these cases, the Docid_Sync table only has one entry, the result of the Docs trigger.

In other instances, the Docs table is updated first, and then the Trans table. In these instances, the Docid_Sync table has two entries - one as the result of the Docs trigger, and another as the result of the Trans trigger.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文