2010-08-12 58 views
0

我需要從TSQL翻譯腳本PLSQL,是這樣的:如何獲得額外行的id在甲骨文

DECLARE @temp_id INT
INSERT INTO表(COL1,COL2)VALUES(1, 2)
SET @temp_id = @@身份

但是,我無法找到類似的全局變量@@身份

甲骨文專家的人的東西嗎?

+0

可能重複[Oracle:如何創建標識列?](http://stackoverflow.com/questions/2053313/oracle-how-to-create-an-identity-column) – DCookie 2010-08-12 14:05:27

+0

順便說一句,在SQL Server上如果觸發器觸發插入其他表,則「@@ identity」可能無法給出正確答案。最佳實踐建議使用'scope_identity()'來代替。 – 2010-08-12 16:46:37

回答

0

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

SequenceName.NEXTVAL下一個值,sequenceName.CURRVAL - 最近使用的值(如@@身份)

INSERT INTO表(ID,COL1,COL2)VALUES(Sequence.NEXTVAL,1,2) ;

SELECT sequence.CURRVAL INTO來自dual的Temp_ID;

1

Michael Pakhantsov的答案僅適用於單用戶單任務環境。 插入和選擇語句是單獨的語句! 多用戶多進程環境中會發生什麼?

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 

一個注意補充道: 當您使用的身份表,系統生成的序列將會產生。 即使放下桌子後,這個序列仍然會存在! 即使sysdba也不能刪除這個序列! 在drop table語句之後,您需要清除recyclebin來刪除它們。