Как получить идентификатор добавленной строки в Oracle - PullRequest
0 голосов
/ 12 августа 2010

Мне нужно перевести скрипт из tsql в plsql, что-то вроде:

DECLARE @temp_id int
INSERT INTO Table (col1, col2) VALUES (1, 2)
SET @temp_id= @@ identity

но у меня возникли проблемы с поиском чего-то похожего на глобальную переменную @@ identity

Кто-нибудь из экспертов Oracle?

Ответы [ 3 ]

6 голосов
/ 12 августа 2010

Предполагается, что у вас есть какой-то триггер для заполнения столбца первичного ключа последовательностью , и вы хотите получить назначенное значение ...

INSERT INTO Table (col1, col2) VALUES (1, 2) 
RETURNING pk_col INTO temp_id
/

Обратите внимание, что синтаксис RETURNING работает только с однострочными вставками.

1 голос
/ 04 декабря 2013

Ответ Михаила Паханцова можно использовать только в среде одного пользователя. Операторы вставки и выбора являются отдельными утверждениями! Что происходит в многопользовательской многопроцессорной среде?

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 не может отбросить эту последовательность! После оператора удаления таблицы требуется корзина очистки, чтобы удалить их.

0 голосов
/ 12 августа 2010

Вам нужно использовать последовательности. (http://psoug.org/reference/sequences.html)

SequenceName.NEXTVAL следующее значение, sequenceName.CURRVAL - последнее использованное значение (например, @@ Identity)

INSERT INTO VALUES таблицы (Id, col1, col2) (Sequence.NEXTVAL, 1, 2);

SELECT sequence.CURRVAL INTO Temp_ID из двойного;

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