Во-первых, у меня это работает в 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;
Затем
- Вам не нужен именованный блок, еслиэто единственный блок.
- Это триггер вставки, поэтому вам не нужно проверять
if inserting
. - Разрешение как сгенерированных, так и введенных пользователем значений в одном столбце является рецептом.для бедствия, но если вам необходимо, вы можете определить это как
when
условие в спецификации триггера. - Язык 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