【问题标题】:Update same table after Insert trigger插入触发器后更新同一张表
【发布时间】:2014-09-27 23:05:11
【问题描述】:

我正在开发一种产品,当有人等待服务超过 15 分钟时,我必须向相关人员发送短信。

为此,我编写了一个程序,当Duration 超过15 时,它会监视一个表并将CUST_ID, CUST_CATEGORY, DURATION 存储在一个单独的表中。该表的表结构是:

Some_Table

CUST_ID CUST_CATEGORY DURATION SMS_STATUS

我写了一个触发器:

触发器

create or replace trigger kiosk_sms_trg 
after insert on Some_Table 
referencing new as new old as old
for each row
BEGIN 
SMS_Proc@My_Server; --Procudure that generates SMS
update Some_Table set status = 'Y' where id = (select max(id) id  from Some_Table where status = 'N'); --Update Table that SMS has been sent
select 'Y' into :new.status from dual;
END;

但它会产生突变问题。我该如何解决?任何帮助将不胜感激。我正在使用 Oracle 11G。

【问题讨论】:

  • 去掉这行referencing new as new old as old你不用了。
  • 我感觉这不对。 SMS_Proc@My_Server; 应该更新该表。
  • 我认为 OP 在使用触发器之前需要对触发器进行一些阅读

标签: oracle stored-procedures triggers oracle11g


【解决方案1】:

我认为在 SOME_TABLE 上不允许 UPDATE,因为它目前正在发生变化。

为什么不把它放在最开始触发触发器的 INSERT 语句之后呢?

INSERT INTO SOME_TABLE ...
update Some_Table set status = 'Y' where id = (select max(id) id  from Some_Table where status = 'N'); --Update Table that SMS has been sent

考虑到您在该 UPDATE 中没有执行任何特定行的操作,我想这将是正确的方法。

正如我在评论中提到的,AFTER INSERT 触发器中的最后一条语句有什么特殊用途吗?它在BEFORE INSERT 触发器中确实有意义。

select 'Y' into :new.status from dual;

【讨论】:

  • Status col默认为N,文本发送完毕后才需要为Y。
  • 我看到您正在使用“AFTER INSERT”触发器。这不应该是发生这种情况的“BEFORE INSERT”触发器吗?
  • 如果我使用Before Insert,前一个客户的记录ID会被选中。
  • @IngilaEjaz 我听不懂你。请通过编辑/添加到您的问题来解释这种情况。
  • @Ingila 在触发前中,id 可以从:new.id 访问(如果它是在触发触发之前设置的)——或者,如果你需要,您可以直接从该触发器的序列中生成它。不需要像 select max(id) ... 这样的次优解决方案来获得这个价值。
【解决方案2】:

您无法更新行级AFTER Trigger 中的同一个表。
将您的行级AFTER INSERT 触发器更改为行级BFEORE INSERT 触发器。

但是您在触发器中 UPDATE stmt 不会影响正在插入的新记录。

想知道怎么做,这很棘手。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-18
    • 2011-10-19
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2021-12-25
    • 2016-12-14
    相关资源
    最近更新 更多