如何获取Oracle中添加的行的ID

时间:2010-08-12 14:01:31

标签: oracle identity auto-increment

我需要将脚本从tsql转换为plsql,例如:

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

但是,我很难找到类似于全局变量@@ identity

的东西

Oracle专家吗?

3 个答案:

答案 0 :(得分:5)

假设您有some kind of trigger to populate the primary key column with a sequence,并且想要获得指定值...

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

请注意,RETURNING语法仅适用于单行插入。

答案 1 :(得分:1)

Michael Pakhantsov的答案仅适用于单用户单任务环境。 insert和select语句是单独的语句! 在多用户多进程环境中会发生什么?

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 id 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

补充说明: 使用identity创建表时,将生成系统生成的序列。 丢弃表后,此序列将继续存在! 即使是sysdba也不能放弃这个序列! 在drop table语句之后,您需要使用purge recyclebin来删除它们。

答案 2 :(得分:0)

您需要使用序列。 (http://psoug.org/reference/sequences.html

SequenceName.NEXTVAL下一个值,sequenceName.CURRVAL - 最新使用的值(如@@ Identity)

INSERT INTO表(Id,col1,col2)VALUES(Sequence.NEXTVAL,1,2);

SELECT sequence.CURRVAL INTO Temp_ID from dual;