PLSQL - Создание триггерных ошибок - PullRequest
0 голосов
/ 23 мая 2018

У меня есть таблица, для которой мне нужно сгенерировать триггер.Ниже приведен код, который у меня есть для этого:

CREATE OR REPLACE EDITIONABLE TRIGGER "MYUSER"."REGISTRATION_TRG" BEFORE
  INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
  AND :NEW.REGISTRATIONID                              IS NULL THEN
  SELECT REGISTRATIONS_SEQ.NEXTVAL
  INTO :NEW.REGISTRATIONID
  FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;

При запуске я получаю следующие ошибки:

Error starting at line 0 in command:
CREATE OR REPLACE EDITIONABLE TRIGGER "MYUSER"."REGISTRATIONS_TRG" BEFORE
  INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
  AND :NEW.REGISTRATIONID                              IS NULL THEN
  SELECT REGISTRATIONS_SEQ.NEXTVAL
  INTO :NEW.REGISTRATIONID
  FROM SYS.DUAL
Error report:
SQL Command: CREATE OR REPLACE EDITIONABLE
Failed: Warning: execution completed with warning

Error starting at line 7 in command:
END IF
Error report:
Unknown Command

Error starting at line 8 in command:
END COLUMN_SEQUENCES
Error report:
Unknown Command

Error starting at line 9 in command:
END
Error report:
Unknown Command

Что я делаю не так?

Спасибо!

1 Ответ

0 голосов
/ 23 мая 2018

Во-первых, у меня это работает в SQL * Plus и в PL / SQL Developer:

create table registrations(registrationid integer);

create sequence registrations_seq;

CREATE OR REPLACE EDITIONABLE TRIGGER "REGISTRATION_TRG" BEFORE
  INSERT ON REGISTRATIONS FOR EACH ROW BEGIN <<COLUMN_SEQUENCES>> BEGIN IF INSERTING
  AND :NEW.REGISTRATIONID                              IS NULL THEN
  SELECT REGISTRATIONS_SEQ.NEXTVAL
  INTO :NEW.REGISTRATIONID
  FROM SYS.DUAL;
END IF;
END COLUMN_SEQUENCES;
END;
/

(я удалил "MYUSER", потому что у меня нет учетной записи с таким именем.)

Однако, вы можете немного упростить это.Для начала стоит аккуратно выложить код на любом языке, поэтому первым шагом будет:

create or replace editionable trigger registration_trg
    before insert on registrations
    for each row
begin
    <<column_sequences>>
    begin
        if inserting and :new.registrationid is null then
            select registrations_seq.nextval into :new.registrationid
            from sys.dual;
        end if;
    end column_sequences;
end;

Затем

  1. Вам не нужен именованный блок, еслиэто единственный блок.
  2. Это триггер вставки, поэтому вам не нужно проверять if inserting.
  3. Разрешение как сгенерированных, так и введенных пользователем значений в одном столбце является рецептом.для бедствия, но если вам необходимо, вы можете определить это как when условие в спецификации триггера.
  4. Язык PL / SQL имеет оператор присваивания :=, поэтому вам не нужно запрашиватьприсваивать значения переменным.

Так почему бы просто:

create or replace trigger registration_trg
    before insert on registrations
    for each row
    when (new.registrationid is null)
begin
    :new.registrationid := registrations_seq.nextval;
end;

Еще проще, начиная с Oracle 12.1 и далее, вам даже не нужен триггер:

drop table registrations;

create table registrations (id integer generated always as identity);

insert into registrations values (default);

select * from registrations;

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