Условный триггер - PullRequest
3 голосов
/ 30 мая 2011
create or replace trigger insert_test_id
before insert on test
where(test.name='Ash')
begin
insert into test(s_no) values('def');
end

мой стол

тест целое число имя varchar2 (200) s_no varchar2 (250)

пожалуйста, скажите мне, что является ошибкой в ​​этом триггере. Я не могу узнать.

Ответы [ 3 ]

5 голосов
/ 30 мая 2011

Быстрый взгляд на онлайн-документацию сказал бы, что условный синтаксис - КОГДА, а не ГДЕ.

Вы также должны ссылаться на столбец, используя ключевое слово NEW, а не имя таблицы.И, как справедливо указывает Гэри, мы можем применить условное предложение только для триггеров 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>

Конечно, я обманул здесь, чтобы сгенерировать ошибку.Если и тестовое значение, и подставляемое значение жестко заданы, проблемы можно избежать.Но если какой-либо из них является поиском, то существует риск рекурсии.


Если вы действительно хотите заменить входное значение, а вместо этого вставить дополнительную строку, вам следует использовать простое присвоение синтаксис размещен @ Lukas .

3 голосов
/ 30 мая 2011

Попробуйте это тогда:

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» делает его триггером уровня оператора, выполняемым для каждой строки, на которую влияет вставка в таблицу. Вот и надо избавиться от ора-04077

1 голос
/ 30 мая 2011

Я не думаю, что вы можете определить триггеры с рекурсивным поведением, как это.Правильный способ сделать это -

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;

Однако при этом будет вставлена ​​только одна запись, а не две, если это было вашим первоначальным намерением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...