如何在Oracle中获取添加行的id

如何在Oracle中获取添加行的id,oracle,identity,auto-increment,Oracle,Identity,Auto Increment,我需要将一个脚本从tsql转换为plsql,类似于: 声明@temp_id int 插入表col1,col2值1,2 设置@temp\u id=@@identity 但是,我很难找到类似全局变量@标识的东西 Oracle专家有人吗?您需要使用序列 SequenceName.NEXTVAL下一个值,SequenceName.CURRVAL-最新使用的值,如@@Identity 插入表Id,col1,col2值序列。NEXTVAL,1,2 从dual中选择sequence.CURRVAL进入临时ID

我需要将一个脚本从tsql转换为plsql,类似于:

声明@temp_id int 插入表col1,col2值1,2 设置@temp\u id=@@identity

但是,我很难找到类似全局变量@标识的东西

Oracle专家有人吗?

您需要使用序列

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

插入表Id,col1,col2值序列。NEXTVAL,1,2

从dual中选择sequence.CURRVAL进入临时ID

您需要使用序列

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

插入表Id,col1,col2值序列。NEXTVAL,1,2

从dual中选择sequence.CURRVAL进入临时ID

假设您有,并且您希望获得指定的值

INSERT INTO Table (col1, col2) VALUES (1, 2) 
RETURNING pk_col INTO temp_id
/
请注意,返回语法仅适用于单行插入。

假定您有,并且您希望获得指定的值

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

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

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
它将输出:

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_输出为:

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
请记住,一次只能插入一行:

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命令未正确结束错误,在临时id中省略返回的id

在Oracle12中,您可以使用identity列并获得类似于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_输出为:

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
增加了一项说明: 使用identity创建表时,将生成系统生成的序列。 即使在删除表之后,此序列仍将继续存在! 即使是sysdba也不能删除这个序列!
在drop table语句之后,您需要清除回收BIN来删除它们。

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
它将输出:

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_输出为:

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
请记住,一次只能插入一行:

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命令未正确结束错误,在临时id中省略返回的id

在Oracle12中,您可以使用identity列并获得类似于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_输出为:

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;
inside trigger 1 Vicky
1
inside trigger 2 Joël
2
1 Vicky
2 Joël
增加了一项说明: 使用identity创建表时,将生成系统生成的序列。 即使在删除表之后,此序列仍将继续存在! 即使是sysdba也不能删除这个序列! 在drop table语句之后,您需要purge RECALLEBIN来删除它们。

顺便说一句,SQL Server上可能存在重复项@@identity可能无法给出正确答案,如果存在触发插入其他表的触发器。最佳做法建议改用scope_identity。顺便说一句,SQL Server上可能存在重复的@@identity可能无法给出正确答案,如果存在触发插入到其他表中的触发器。最佳实践建议使用范围标识。