【问题标题】:Conditional Trigger条件触发
【发布时间】:2011-09-04 15:19:03
【问题描述】:
create or replace trigger insert_test_id
before insert on test
where(test.name='Ash')
begin
insert into test(s_no) values('def');
end

我的桌子是

测试 id 整数 名称 varchar2(200) s_no varchar2(250)

请告诉我这个触发器的错误是什么。我查不出来。

【问题讨论】:

  • 请贴出错误信息!
  • ORA-04079: 无效的触发器规范 这是错误信息

标签: oracle triggers


【解决方案1】:

我认为您不能像这样定义具有递归行为的触发器。正确的做法是

create or replace trigger insert_test_id
before insert on test

-- note: it is "when", not "where"
when(test.name='Ash')
begin

  -- this is how you override a field from within the trigger
  :new.s_no := 'def';
end;

但是,如果这是您的初衷,这只会插入一条记录,而不是两条。

【讨论】:

  • 感谢您的回复我的朋友。但这不起作用。它再次给出错误'ORA-04077:WHEN 子句不能与表级触发器一起使用'
【解决方案2】:

快速浏览online documentation 会告诉您条件语法是 WHEN 而不是 WHERE。

您还应该使用 NEW 关键字而不是表名来引用列。正如 Gary 正确指出的那样,我们只能将条件子句应用于 ROW LEVEL 触发器:

SQL> create or replace trigger insert_test_id
  2  before insert on t23
  3  for each row
  4  when (new.name='Ash')
  5  begin
  6      insert into t23(name) values('def');
  7  end;
  8  /

Trigger created.

SQL> insert into t23 values ('abc')
  2  /

1 row created.

SQL> select name from t23
  2  /

NAM
---
abc

1 rows selected.

SQL>

条件也有效...

SQL> insert into t23 values ('Ash')
  2  /

1 row created.

SQL> select name from t23
  2  /

NAM
---
abc
def
Ash

3 rows selected.

SQL>

它甚至适用于多行......

SQL> insert into t23
  2  select txt from t42
  3  /

4 rows created.

SQL> select name from t23
  2  /

NAM
---
abc
def
Ash
XXX
ZZZ
ABC
DEF

7 rows selected.

SQL>

那么问题是什么?这个:

SQL> create or replace trigger insert_test_id
  2  before insert on t23
  3  for each row
  4  when (new.name='def')
  5  begin
  6      insert into t23(name) values('def');
  7  end;
  8  /

Trigger created.

SQL> insert into t23 values ('def')
  2  /
insert into t23 values ('def')
            *
ERROR at line 1:
ORA-00036: maximum number of recursive SQL levels (50) exceeded
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger 'APC.INSERT_TEST_ID'
ORA-06512: at "APC.INSERT_TEST_ID", line 2
ORA-04088: error during execution of trigger


SQL>

我当然在这里作弊,产生错误。如果测试值和替换值都被硬编码,则可以避免问题。但如果其中任何一个是查找,则存在递归风险。


如果您真正想要做的是替换输入值而不是插入额外的行,您应该使用simple assignment syntax posted by @Lukas

【讨论】:

    【解决方案3】:

    那就试试这个吧:

    CREATE OR REPLACE TRIGGER insert_test_id
    BEFORE INSERT ON test
    WHEN(new.name='Ash')
    FOR EACH ROW
    BEGIN
      :new.s_no := 'def';
    END;
    

    “FOR EACH ROW”使其成为语句级触发器,针对受插入表影响的每一行执行。那应该摆脱 ora-04077

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      • 2013-09-16
      • 2022-11-19
      • 1970-01-01
      • 2011-10-05
      相关资源
      最近更新 更多