逐个动态获取记录Oracle

时间:2017-01-16 16:19:05

标签: oracle procedure

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

直到现在我所做的是:

  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;

1 个答案:

答案 0 :(得分:0)

无法以这样的方式定义V_ROW,以使PL / SQL块正确运行,直到运行时才知道其名称和结构的输入表。

要使您的方法有效,您需要使用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 */附带了一些在使用之前应该考虑的警告,但这可能是实现目标的一种更简单的方式。