Oracle:将行类型数据插入另一个表

Fra*_*ank 7 oracle plsql insert rowtype

我有一个名为event的表 ,并创建了另一个全局临时表tmp_event,其中包含与事件相同的列和定义.是否可以使用此方法将事件中的记录插入tmp_event?

DECLARE
   v_record event%rowtype;
BEGIN 
   Insert into tmp_event values v_record;
END;
Run Code Online (Sandbox Code Playgroud)

事件表中有太多列,我想尝试这个,因为我不想列出所有列.

忘了提一下:我会在触发器中使用它,这个v_record可以作为对象:在EVENT表上插入之后是新的吗?

Ann*_*awn 18

插入一行 -

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;
Run Code Online (Sandbox Code Playgroud)

或者更精细的版本来插入所有行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;
/
Run Code Online (Sandbox Code Playgroud)

在一个触发器中,是的,它可能,但它像鸡或鸡蛋.您必须rowtype使用:new列值初始化每个字段,例如-

v_record.col1 := :new.col1;
v_record.col2 := :new.col2;
v_record.col3 := :new.col3;
....
Run Code Online (Sandbox Code Playgroud)

显然,上面的PLSQL示例不能在触发器中使用,因为它会抛出一个变异的触发器错误.还有就是让你获得比单独访问每个列正如我上面介绍的其他触发整个行没有别的办法,所以如果你做这一切,为什么不直接用:new.colINSERT into temp_event自身,会为你节省大量的工作.


此外,因为你说要提及所有列是很多工作,(在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;
Run Code Online (Sandbox Code Playgroud)