条件触发器

时间:2011-05-30 07:44:29

标签: oracle triggers

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)

请告诉我这个触发器中的错误是什么。我无法找到答案。

3 个答案:

答案 0 :(得分:5)

快速浏览online documentation会告诉您条件语法是WHEN not 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

答案 1 :(得分: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

答案 2 :(得分: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;

但是,这只会插入一条记录,而不是两条记录,如果那是你原来的意图。