我需要從TSQL翻譯腳本PLSQL,是這樣的:如何獲得額外行的id在甲骨文
DECLARE @temp_id INT
INSERT INTO表(COL1,COL2)VALUES(1, 2)
SET @temp_id = @@身份
但是,我無法找到類似的全局變量@@身份
甲骨文專家的人的東西嗎?
我需要從TSQL翻譯腳本PLSQL,是這樣的:如何獲得額外行的id在甲骨文
DECLARE @temp_id INT
INSERT INTO表(COL1,COL2)VALUES(1, 2)
SET @temp_id = @@身份
但是,我無法找到類似的全局變量@@身份
甲骨文專家的人的東西嗎?
您需要使用序列。 (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;
假設你有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
/
注意,返回的語法只有單行插入工作。
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來刪除它們。
可能重複[Oracle:如何創建標識列?](http://stackoverflow.com/questions/2053313/oracle-how-to-create-an-identity-column) – DCookie 2010-08-12 14:05:27
順便說一句,在SQL Server上如果觸發器觸發插入其他表,則「@@ identity」可能無法給出正確答案。最佳實踐建議使用'scope_identity()'來代替。 – 2010-08-12 16:46:37