2017-01-16 73 views
0

我正在创建一个可以接受2个表名的动态过程。从一个表中获取记录,并在某个记录(让我们说100条记录)后,我必须发出提交命令。 tabName和temp_tabName都是相同的。因为我在第一个表中有数十亿条记录,所以我在每10000条记录之后执行提交以摆脱撤消表空间问题。动态获取记录Oracle

到目前为止我所做的是:

CREATE OR REPLACE PROCEDURE MyProdecure (
     tabName  IN USER_TABLES.table_name%TYPE, 
     temp_tabName IN USER_TABLES.table_name%TYPE 
    ) 
    IS 
     v_sql   VARCHAR2 (100) := 'select * from ' || tabName; 
     TEMP_CURSOR SYS_REFCURSOR; 
     COUNT   NUMBER (6) := 0; 
    BEGIN 
     OPEN TEMP_CURSOR FOR v_sql; 

     LOOP 
      FETCH TEMP_CURSOR INTO V_ROW; 

     --================================================================================= 

     /* 
      * I need the code here to fetch the 100 record from TEMP_CURSOR into a Variable 
      * and insert into the second table. or one record increment the count and if 
      * count>= 100 commit 
      *What would be the data type of V_ROW. How to fetch the data from V_ROW and complete the insert into command. 
      */ 

     --================================================================================ 
      EXIT WHEN TEMP_CURSOR%NOTFOUND; 
     END LOOP; 

     CLOSE TEMP_CURSOR; 
    END MyProdecure; 
+0

我不确定它是否正是你想要的,但你可以做一个如果获得{temp_cursor%rowcount = 100}。这会让你获得第100行阅读的时刻。 –

+0

为什么每次一个?你为什么不能一次处理整个设备?您是否对每个100条记录进行额外的处理?在循环中这样做似乎效率低下,除非你有额外的限制。 – xQbert

+3

这是一个功课题吗?一般来说,分批进行并不是一种好的做法。 – Boneist

回答

0

有没有办法以这样的方式来正确地作出你的PL/SQL块工作,为输入表,其名称和结构来定义V_ROW是未知直到运行时。

要使您的方法奏效,您需要使用DBMS_SQL

您是否考虑过以下的变体,绕过绝大多数的UNDO代?

CREATE OR REPLACE PROCEDURE MyProcedure (
     tabName  IN USER_TABLES.table_name%TYPE, 
     temp_tabName IN USER_TABLES.table_name%TYPE 
    ) 
    IS 
    l_log_io NUMBER; 
    C_BLOCK_SIZE NUMBER := 8192; -- assuming 8192 byte block size 
    l_undo_bytes NUMBER; 
BEGIN 
    EXECUTE IMMEDIATE 'INSERT /*+ APPEND */ INTO ' || temp_tabName || 
    ' SELECT * FROM ' || tabName; 

    select t.log_io, t.used_ublk*C_BLOCK_SIZE undo_bytes 
    into l_log_io, l_undo_bytes 
    from v$transaction t 
    where t.addr = (SELECT s.taddr FROM v$session s WHERE s.sid = USERENV('SID')); 

    dbms_output.put_line('Undo bytes used: ' || l_undo_bytes); 
END; 

INSERT /*+ APPEND */附带了一些注意事项,你应该考虑使用它之前,但它可能是实现你的目标的一个更简单的方法。