Обновление после триггера вставки на той же таблице - PullRequest
1 голос
/ 03 августа 2011

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

create or replace trigger trigger_A
after insert on table_A
begin
  update table_A set col1=1 where col1 is null;
end;

У меня есть приложение, которое будет выполнять только col2 будет вставлено, а col1 останется нулевым.так что мой триггер даст значение для col1 после вставки строки.Но я получаю сообщение об ошибке «Триггер сбой и недействителен», когда строка вставлена.Как это сделатьТИА.

Ответы [ 2 ]

6 голосов
/ 03 августа 2011

Если вы хотите назначить простое значение по умолчанию, самый простой способ - объявить его в таблице с помощью предложения DEFAULT.

SQL> create table t42
  2    ( col1 number default 1 not null
  3      , col2 date)
  4  /

Table created.

SQL> insert into t42 (col2) values (sysdate)
  2  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2
---------- ---------
         1 03-AUG-11

SQL>

Это работает с литералами или псевдоколонками, такими как SYSDATE или USER. Если вы хотите получить более сложное значение с помощью пользовательской функции или последовательности, вам нужно будет использовать триггер.

Вот новая версия таблицы ...

SQL> create table t42
  2    ( col1 number default 1 not null
  3      , col2 date default sysdate
  4      , col3 varchar2(30) default user
  5      , col4 number )
  6  /

Table created.

SQL>

... с триггером:

SQL> create or replace trigger t42_trg
  2      before insert or update
  3      on t42
  4      for each row
  5  begin
  6      if :new.col4 is null
  7      then
  8          :new.col4 := my_seq.nextval;
  9      end if;
 10  end;
 11  /

Trigger created.

SQL> insert into t42 (col1, col2, col3)
  2  values (99, sysdate, 'MR KNOX')
  3  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2      COL3                                 COL4
---------- --------- ------------------------------ ----------
        99 03-AUG-11 MR KNOX                               161

SQL>

Обратите внимание, что хотя каждый столбец в таблице имеет значение по умолчанию, мне нужно заполнить хотя бы один столбец, чтобы сделать SQL действительным:

SQL> insert into t42 values ()
  2  /
insert into t42 values ()
                        *
ERROR at line 1:
ORA-00936: missing expression


SQL>

Но я могу передать NULL в COL4, чтобы получить полностью дефолтную запись:

SQL> insert into t42 (col4) values (null)
  2  /

1 row created.

SQL> select * from t42
  2  /

      COL1 COL2      COL3                                 COL4
---------- --------- ------------------------------ ----------
        99 03-AUG-11 MR KNOX                               161
         1 03-AUG-11 APC                                   162

SQL>

Предупреждение лектора: мой триггер использует новый синтаксис 11g. В предыдущих версиях мы должны присвоить значение последовательности с помощью инструкции SELECT:

select my_seq.nextval
into :new.col4
from dual;
0 голосов
/ 14 июня 2017

Вы не можете обновить таблицу, в которой вызывается триггер:

Внутри сохраненной функции или триггера запрещено изменять таблица, которая уже используется (для чтения или записи) оператор, который вызвал функцию или триггер.

Это приведет к ошибке 1442:

Error Code: 1442
Can't update table 'MyTable' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.

Короче говоря, нам не разрешено обновлять используемую таблицу - но ваш случай прост: хотите обновить поле, только если оно пустое, для этого выберите триггер BEFORE INSERT ON, чтобы вы могли обновить все поля новая / текущая запись / строка (так как она еще не была введена):

DELIMITER //
DROP TRIGGER IF EXISTS trigger_A//
CREATE TRIGGER trigger_A BEFORE INSERT ON table_A
FOR EACH ROW BEGIN
    IF NEW.col1 IS NULL THEN
        set NEW.col1 = <some-value>;
    ENF IF;
END;
//
DELIMITER ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...