9

我有一个名为 event的表,并创建了另一个具有相同列和 event 定义的全局临时表tmp_event 。是否可以使用 this 将事件中的记录插入 tmp_event ?

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

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

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

4

3 回答 3

21

要插入一行 -

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 示例不能在触发器中使用,因为它会引发 mutating trigger 错误。除了像我上面解释的那样单独访问每一列之外,没有其他方法可以让您在触发器中获取整行,因此,如果您执行所有这些操作,为什么不直接:new.col在其INSERT 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;
于 2012-12-13T19:30:06.067 回答
2

有一种方法可以使用 %Rowtype e将多行插入到表中。

结帐下面的例子。

DECLARE
TYPE v_test IS   TABLE OF TEST_TAB%rowtype;
  v_test_tab v_test ;


 EXECUTE immediate ' SELECT  * FROM TEST_TAB ' bulk collect INTO v_test_tab ;
  dbms_output.put_line('v_test_tab.count -->'||v_test_tab.count);
  FOR i IN 1..v_test_tab.count
  LOOP
    INSERT INTO TEST_TAB_1 VALUES v_test_tab
      (i
      ) ;
  END LOOP;

END;
于 2018-07-30T06:25:57.793 回答
0

总结完整的工作示例...

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;
    FORALL i IN 1..l_tab.count
        Insert into tmp_event values l_tab(i);
    commit;
  END LOOP;
  CLOSE c_data;
END;
/
于 2020-05-25T13:43:01.577 回答