Oracle запускает создание автозапуска

Я никогда не создавал триггер в Oracle раньше, поэтому я ищу какое-то направление.

Я хотел бы создать триггер, который увеличивает идентификатор на единицу, если ID не содержится в инструкции insert.

Идентификатор должен начинаться с 10000, а когда вставлена ​​запись, следующий идентификатор должен быть 10001. Если оператор insert содержит идентификатор, он должен переопределить автоматическое приращение.

т

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird')

должен выглядеть так:

firstname lastname id

Микаэль Джордан 10000

Ларри Берд 10001

insert into t1 (firstname, lastname, id) values ('Scottie','Pippen',50000)

должен выглядеть так:

firstname lastname id

Микаэль Джордан 10000

Ларри Берд 10001

Скотти Пиппен 50000

Ответ 1

Что-то вроде этого будет работать на 11g

CREATE SEQUENCE t1_id_seq 
  start with 10000 
  increment by 1;

CREATE TRIGGER trigger_name
  BEFORE INSERT ON t1
  FOR EACH ROW
DECLARE
BEGIN
  IF( :new.id IS NULL )
  THEN
    :new.id := t1_id_seq.nextval;
  END IF;
END;

Если вы используете более раннюю версию, вам нужно сделать SELECT INTO, чтобы получить следующее значение из последовательности

CREATE TRIGGER trigger_name
  BEFORE INSERT ON t1
  FOR EACH ROW
DECLARE
BEGIN
  IF( :new.id IS NULL )
  THEN
    SELECT t1_id_seq.nextval
      INTO :new.id
      FROM dual;
  END IF;
END;

Помните, что последовательности Oracle не являются свободными от пробелов. Поэтому вполне возможно, что конкретные значения будут пропущены по целому ряду причин. Ваша первая вставка может иметь идентификатор 10000, а второй может иметь идентификатор 10020, если он выполнил минуты, часы или дни позже.

Кроме того, имейте в виду, что Oracle не поддерживает указание нескольких строк в предложении VALUES, как это делает MySQL. Поэтому вместо

insert into t1 (firstname, lastname) values ('Michael','Jordan'),('Larry','Bird')

вам понадобятся два отдельных оператора INSERT

insert into t1 (firstname, lastname) values ('Michael','Jordan');
insert into t1 (firstname, lastname) values ('Larry','Bird');

Ответ 2

Я бы рекомендовал закодировать этот триггер с условием самого триггера, а не в блоке sql.

CREATE OR REPLACE TRIGGER your_trigger
BEFORE INSERT ON your_table
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
WHEN (new.id IS NULL)
  BEGIN
    SELECT your_sequence.nextval
    INTO :new.id
    FROM dual;
  END;
/

С помощью этого решения триггер выполняется только в том случае, если условие соответствует (id равно null).

В противном случае триггер всегда выполняется, и блок проверяет, равен ли id. БД должна выполнить блок SQL, который ничего не делает при не нулевых значениях.