使用触发器在新行上设置列

Posted

技术标签:

【中文标题】使用触发器在新行上设置列【英文标题】:Setting a column on a new row with a trigger 【发布时间】:2015-09-25 11:20:51 【问题描述】:

我有一个表名dblog,其中的架构类似于

data_balance_id number(8) primary key,
plan_id number(6) not null,
start_date date default current_date,
end_date date not null);

所以我正在尝试创建一个触发器,当插入发生时将更新enddate 列。 enddate 将更新为从插入之日起 30 天。我的触发代码是

CREATE OR REPLACE TRIGGER trg
BEFORE INSERT
ON dblog FOR EACH ROW

BEGIN
  INSERT INTO dblog (end_date) values (SYSDATE()+30);
END;
/

插入查询如下

insert into dblog (db_id, planid) values (12,123);

触发器的创建没有任何错误。但是在插入时我收到以下错误

insert into dblog (db_id, planid) values (12,123)
             *
ERROR at line 1:
ORA-00036: maximum number of recursive SQL levels (50) exceeded
ORA-06512: at "E1038351.TRG1", line 2

【问题讨论】:

你要更新,所以不要再插入一行:只需设置:new.end_date的值 你正在做一个插入前插入同一张表,无限循环 【参考方案1】:

您只想修改:new 伪记录。像这样的

CREATE OR REPLACE TRIGGER trg
  BEFORE INSERT ON dblog 
  FOR EACH ROW
BEGIN
  :new.end_date := sysdate + 30;
END;

如果您不希望 end_date 具有时间组件(或者,您希望时间组件是午夜),您会想要 trunc(sysdate) + 30

【讨论】:

报错PLS-00049: bad bind variable 'NEW.END_DATE' @AnirbanNag'tintinmj' - 你确定你使用了冒号前缀吗?你用的是什么客户端?您的客户端可能会尝试将带有 : 前缀的任何内容解释为绑定变量。 抱歉输入错误。一切正常。【参考方案2】:

您正在尝试插入另一行,这也会重新触发触发器。

在触发器中,您可以使用变量 :NEW:OLD 访问行。

如果您插入时,:OLD 为 null ,因为您的表中还没有它。

因此,在插入行之前,您可以像这样更新他的列:

:NEW.END_DATE = SYSDATE+30;

【讨论】:

以上是关于使用触发器在新行上设置列的主要内容,如果未能解决你的问题,请参考以下文章

Google 表格 - 创建新行时自动替换值

插入新行时在谷歌电子表格上触发脚本

半计算列只能在插入触发器后使用?

从 Google 工作表过滤器添加的新行上的另一个邮件合并触发器

在不提交表单的情况下触发 Google 脚本

如果出现多个错误,则将 :new 中的列用于触发器