Ответ Михаила Паханцова можно использовать только в среде одного пользователя.
Операторы вставки и выбора являются отдельными утверждениями!
Что происходит в многопользовательской многопроцессорной среде?
Process 1 insert
Process 2 insert
Process 2 select returns the is the id by process 2 insert
Process 1 select returns the is the id by process 2 insert NOT the process 1 insert
Никогда не программируйте таким образом, даже не думайте об этом.
Вам нужна атомарная операция, а это означает, что переключение задач не повлияет на нее.
Ответ APC будет:
create table FOO (
id number primary key,
name varchar2(100)
);
create sequence FOO_seq;
create or replace trigger FOO_trg
before insert on FOO
for each row
begin
select FOO_seq.nextval into :new.id from dual;
dbms_output.put_line('inside trigger '||:new.id||' '||:new.name);
end;
/
declare
temp_id number:=10;
begin
INSERT INTO FOO (id, name) VALUES (null, 'Vicky') RETURNING id INTO temp_id;
dbms_output.put_line(temp_id);
rollback;
INSERT INTO FOO (id, name) VALUES (null, 'Joël') RETURNING id INTO temp_id;
dbms_output.put_line(temp_id);
commit;
end;
/
select * from FOO;
drop table FOO;
drop sequence FOO_seq;
Будет выведено:
table FOO created.
sequence FOO_SEQ created.
TRIGGER FOO_TRG compiled
anonymous block completed
ID NAME
------ --------
2 joël
table FOO dropped.
sequence FOO_SEQ dropped.
dbms_output будет:
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
Помните, что вы можете использовать это только для вставки одной строки за раз:
insert all
into foo(id,name) values(null,'Vicky')
into foo(id,name) values(null,'Joël')
SELECT null,'none' FROM dual RETURNING id INTO temp_id;
Дает PL / SQL: ORA-00933: ошибка команды SQL неправильно завершилась, пропустите идентификатор RETURNING INTO temp_id.
В Oracle 12 вы можете использовать столбец идентификации и получить что-то похожее на SQLServer и MySql.
CREATE TABLE foo (
id NUMBER GENERATED ALWAYS AS IDENTITY,
name VARCHAR2(30)
);
/
declare
temp_id varchar2(100);
begin
INSERT INTO foo(name) VALUES ('Vicky') RETURNING id||' '||name INTO temp_id;
dbms_output.put_line(temp_id);
INSERT INTO foo(name) VALUES ('Joël') RETURNING id||' '||name INTO temp_id;
dbms_output.put_line(temp_id);
end;
/
drop table foo;
purge recyclebin;
dbms_output будет:
1 Vicky
2 Joël
Добавлена одна заметка:
При создании таблицы с использованием идентификатора будет сгенерирована системная последовательность.
Эта последовательность будет продолжать существовать даже после удаления таблицы!
Даже sysdba не может отбросить эту последовательность!
После оператора удаления таблицы требуется корзина очистки, чтобы удалить их.