2012-12-13 118 views
5

我有一臺名爲事件,並創造了另一個全局臨時表tmp_event具有相同的列和定義與事件。是否有可能在事件中插入記錄到tmp_event使用它?甲骨文:插入行類型的數據到另一個表

DECLARE 
    v_record event%rowtype; 
BEGIN 
    Insert into tmp_event values v_record; 
END; 

事件表中有太多的列,我想嘗試一下,因爲我不想列出所有的列。

忘記提及:我會在觸發器中使用它,可以在插入EVENT表後將此v_record作爲對象:new

+0

更新了在'trigger'中使用的答案。 – Annjawn

+0

我在這裏回答了類似的問題:http://stackoverflow.com/a/26343423/2235483][1] [1]:http://stackoverflow.com/a/26343423/2235483 – Rusty

回答

17

要插入一個行向

DECLARE 
    v_record event%rowtype; 
BEGIN 
    SELECT * INTO v_record from event where rownum=1; --or whatever where clause 
    Insert into tmp_event values v_record; 
END; 

或者更詳盡的版本,從event插入所有行 -

DECLARE 
    TYPE t_bulk_collect_test_tab IS TABLE OF event%ROWTYPE; 

    l_tab t_bulk_collect_test_tab; 

    CURSOR c_data IS 
    SELECT * 
    FROM event; 
BEGIN 
    OPEN c_data; 
    LOOP 
    FETCH c_data 
    BULK COLLECT INTO l_tab LIMIT 10000; 
    EXIT WHEN l_tab.count = 0; 

    -- Process contents of collection here. 
    Insert into tmp_event values v_record; 
    END LOOP; 
    CLOSE c_data; 
END; 
/

在觸發,是有可能的,但它像先有雞還是蛋。你必須在rowtype:new列值的各個領域初始化喜歡 -

v_record.col1 := :new.col1; 
v_record.col2 := :new.col2; 
v_record.col3 := :new.col3; 
.... 

顯然,PLSQL上面的例子不能在觸發器使用,因爲它會拋出一個突變觸發錯誤。除了上面解釋的單獨訪問每列外,沒有其他方式可以讓整行訪問觸發器,所以如果你這樣做,爲什麼不直接在INSERT into temp_event本身中直接使用:new.col,將爲您節省大量工作。


而且因爲你說這是一個大量的工作,更何況所有列,(在的Oracle 11gR2中)這裏是這樣做,通過生成INSERT聲明和動態執行它(儘管不是用於測試的快捷方式性能)。

CREATE OR REPLACE TRIGGER event_air --air stands for "after insert of row" 
AFTER INSERT ON EVENT 
FOR EACH ROW 
    L_query varchar2(2000); --size it appropriately 
BEGIN 

    SELECT 'INSERT INTO tmp_event VALUES ('|| listagg (':new.'||column_name, ',') 
              WITHIN GROUP (ORDER BY column_name) ||')' 
    INTO l_query 
    FROM all_tab_columns 
    WHERE table_name='EVENT'; 

    EXECUTE IMMEDIATE l_query; 

EXCEPTION 
    WHEN OTHERS THEN 
     --Meaningful exception handling here 
END; 
+0

我將數據存儲到tmp_event表中是爲了避免突變觸發錯誤。我更新或插入事件表,並將新記錄添加到tmp_event表中,然後訪問tmp_table中的內容,這將工作嗎? – Frank

+0

是的。只要您不從觸發器所在的表中「選擇」,它就不會拋出突變的觸發器錯誤。 – Annjawn

+0

@LucM有什麼特點? 「突變觸發器」是一個適用於所有版本Oracle數據庫的錯誤。 – Annjawn