2011-03-16 124 views

回答

14

您不能使用INSERT中的RETURNING BULK COLLECT。 這種方法可以與更新工作,並刪除howeveer:

create table test2(aa number) 
/
insert into test2(aa) 
     select level 
     from dual 
     connect by level<100 
/  

set serveroutput on 
declare 
    TYPE t_Numbers IS TABLE OF test2.aa%TYPE 
     INDEX BY BINARY_INTEGER; 
     v_Numbers t_Numbers; 
     v_count number; 
begin 


update test2 
    set aa = aa+1 
returning aa bulk collect into v_Numbers; 

    for v_count in 1..v_Numbers.count loop 
     dbms_output.put_line('v_Numbers := ' || v_Numbers(v_count)); 
    end loop; 

end; 

你可以得到它與這篇文章中所描述的幾個額外的步驟(做一個FORALL INSERT利用TREAT) 工作:

returning with insert..select

Ť

利用他們創建的示例,並且將其應用到TEST2測試表

CREATE or replace TYPE ot AS OBJECT 
    (aa number); 
/


CREATE TYPE ntt AS TABLE OF ot; 
/

set serveroutput on 
DECLARE 

     nt_passed_in ntt; 
     nt_to_return ntt; 

     FUNCTION pretend_parameter RETURN ntt IS 
      nt ntt; 
     BEGIN 
      SELECT ot(level) BULK COLLECT INTO nt 
     FROM dual 
     CONNECT BY level <= 5; 
     RETURN nt; 
     END pretend_parameter; 

    BEGIN 

     nt_passed_in := pretend_parameter(); 

     FORALL i IN 1 .. nt_passed_in.COUNT 
     INSERT INTO test2(aa) 
     VALUES 
     (TREAT(nt_passed_in(i) AS ot).aa 
     ) 
     RETURNING ot(aa) 
     BULK COLLECT INTO nt_to_return; 

     FOR i IN 1 .. nt_to_return.COUNT LOOP 
     DBMS_OUTPUT.PUT_LINE(
      'Sequence value = [' || TO_CHAR(nt_to_return(i).aa) || ']' 
      ); 
     END LOOP; 

    END; 
/
+0

+1很好的例子! – 2011-03-16 13:11:55

+0

太酷了!留給我的唯一問題是聲明對象類型。無法在包中聲明對象類型... – 2011-03-16 13:52:13

-2

這並不像您想象的那麼容易,當然也不像使用MySQL那麼容易。 Oracle不會跟蹤最後一次插入,從而可以對結果進行ping操作。

您需要制定一些其他方式來做到這一點,您可以使用ROWID做到這一點 - 但這有其缺陷。

這個環節討論過這個問題:http://forums.oracle.com/forums/thread.jspa?threadID=352627

+0

這與要求的問題沒有關係 - 它不是確定任何會話插入的最後一行,而是關於從特定的INSERT語句返回一組值。 – 2011-03-16 12:30:49

0

因爲插入是基於選擇,甲骨文假設你是允許多行與語法插入。在這種情況下,請查看返回子句文檔的多行版本,因爲它表明您需要使用BULK COLLECT將所有插入行的值檢索到結果集合中。

畢竟,如果你的插入查詢創建了兩行 - 哪個返回值會把它放到一個變量中?

編輯 - 事實證明,這並不工作,因爲我曾想過....它!

+0

我試過,但我得到了一個ORA 009333. SQL命令沒有正確地結束後的地方。集合類型是一個好主意。 – 2011-03-16 12:27:26

+0

正如Tony在他的回答中所說的那樣,BULK COLLECT並不適用於INSERT--至少在10g以及更早的時候。我不清楚這是否在11g中發生了變化。 – 2011-03-16 12:34:47

+0

是的,我認爲這工作,但它似乎沒有。對不起,不好的建議。 – 2011-03-16 12:35:20

11

不幸的是,這是不可能的。 RETURNING僅適用於INSERT ... VALUES語句。有關此主題的討論,請參見this Oracle forum thread

+0

+1是正確的 – 2011-03-16 12:37:38