Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle 批量收集和dbms_sql的使用_Oracle_Oracle11g - Fatal编程技术网

Oracle 批量收集和dbms_sql的使用

Oracle 批量收集和dbms_sql的使用,oracle,oracle11g,Oracle,Oracle11g,我阅读了更多关于dbms_sql的批量收集和使用的内容,并尝试将其应用于我的一个过程 在我的存储过程中,核心逻辑是从另一个表的值插入到一个表中 CREATE OR replace PROCEDURE My_procedure (pi_date IN DATE, po_error OUT VARCHAR2, p

我阅读了更多关于dbms_sql的批量收集和使用的内容,并尝试将其应用于我的一个过程 在我的存储过程中,核心逻辑是从另一个表的值插入到一个表中

CREATE OR replace PROCEDURE My_procedure (pi_date       IN DATE,
                                          po_error      OUT VARCHAR2,
                                          po_error_desc OUT nocopy VARCHAR2)
AS
  curr_date DATE;
BEGIN
    CURR_DATE := PI_DATE;

    INSERT INTO t1
                (col1,
                 col2,
                 col3,
                 col4,
                 col5)
    SELECT t2.col1,
           t2.col2,
           t2.col3,
           t2.col4,
           CURR_DATE
EXCEPTION
  WHEN OTHERS THEN
             PO_ERROR := -1;

             PO_ERROR_DESC := 'proc nam : '
                              || 'my_procedure'
                              || ', err_num :'
                              || SQLCODE
                              || ' | , err_msg :'
                              || SQLERRM;

             ROLLBACK;

             DBMS_SESSION.free_unused_user_memory;
END;
然而,由于要插入到另一个表中的数据是巨大的,在我的第二个修改过程中

我使用了批量收集和dbms_sql,如下所示

CREATE OR replace PROCEDURE My_procedure (pi_date       DATE,
                                          po_error      OUT VARCHAR2,
                                          po_error_desc OUT nocopy VARCHAR2)
AS
  v_curr_date DATE;
  l_col1                       dbms_sql.Varchar2_Table;
  l_col2                       dbms_sql.Varchar2_Table;
  l_col3                       dbms_sql.Number_Table;
  l_col4                       dbms_sql.Number_Table;

  CURSOR c1 IS
    SELECT *
    FROM   t2;

BEGIN
    V_CURR_DATE := PI_DATE;

    PO_ERROR := 0;

    OPEN c1;

    LOOP
        FETCH c1 bulk collect INTO l_col1, l_col2, l_col3, l_col4 limit 1000;

        forall indx IN 1..l_col1.COUNT
          INSERT INTO t2
                      (col1,
                       col2,
                       col3,
                       col4,
                       col5)
          VALUES      (L_col1(indx),
                       L_col2(indx),
                       L_col3(indx),
                       L_col4(indx),
                       V_CURR_DATE);

EXCEPTION
  WHEN OTHERS THEN
             PO_ERROR := -1;

             PO_ERROR_DESC := 'proc nam : '
                              || 'my_procedure'
                              || ', err_num :'
                              || SQLCODE
                              || ' | , err_msg :'
                              || SQLERRM;

             ROLLBACK;

             DBMS_SESSION.free_unused_user_memory;
END; 
所以这里是我的第二个例子,我已经按照文档使用了批量收集

有人能指出
dbms\u sql.Varchar2\u Table
的确切用法吗

如上所示,如果col1的实际长度是VARCHAR2(40),但是
dbms\u sql。VARCHAR2\u表使用
VARCHAR2(2000)


当您使用
LIMIT
子句时,批量收集循环需要是一个完整循环:

-- Open the cursor
OPEN cursor_name;
-- Loop through cursor records
LOOP

   -- Fetch the cursor results into a collection limited to a set figure
   FETCH cursor_name BULK COLLECT INTO table
   LIMIT 1000;

   -- For every record in the collection
   FORALL x IN INDICES OF table
      INSERT INTO target_table
      (col)
      VALUES
      table(x);

   -- Set up the limit loop exit criteria
   EXIT WHEN table.COUNT < 1000; -- Less that the limit you set    
-- End the loop
END LOOP;
-- Close the cursor
CLOSE cursor_name;
——打开光标
打开游标名称;
--循环浏览游标记录
环
--将光标结果提取到限制在设定图形范围内的集合中
将游标\u名称批量收集到表中
限1000;
--对于集合中的每个记录
表的索引中的所有x
插入到目标_表中
(col)
价值观
表(x);
--设置限制循环退出条件
当table.COUNT<1000时退出;--低于你设定的限制
--结束循环
端环;
--关闭光标
关闭光标和名称;
这个伪代码片段应该可以帮助您找到正确的路径,让批量代码正常工作。您当前对
DBMS\u SQL
表的声明看起来不错


希望能有帮助……

你的确切问题是什么?您提供的代码充满语法错误。您应该提供您正在使用的确切来源,并提及您遇到的问题。我的问题是,我在第二个示例中使用的方法,即使用批量收集并使用dbms_sql插入到另一个表中,是否正确。希望这是好的。谢谢我关于dbms_sql的问题如上所示,如果col1的实际长度是VARCHAR2(40),但是dbms_sql.VARCHAR2_表使用VARCHAR2(2000),并且根据oracle文档,VARCHAR2_表是类型VARCHAR2_表是VARCHAR2(2000)的表,通过二进制_整数进行索引;那么,当实际长度为40时,为什么要使用2000空格呢?它是一个方便的构造函数,可以快速有效地使用包含
VARCHAR2
值的表。如果您真的担心VARCHAR2(2000)数组使用的额外字节,请创建自己的集合,最大长度为40
TYPE array_40_chartype是由二进制_整数组成的VARCHAR2(40)索引表
然后使用以下类型声明一个表:
array\u 40\u char array\u 40\u chartype瞧。感谢Ollie在您的示例中将游标\u名称批量收集到表中,这里的表是一种收集类型,对吗?是的。这是一个收藏。我通常使用关联数组进行批量收集。
-- Open the cursor
OPEN cursor_name;
-- Loop through cursor records
LOOP

   -- Fetch the cursor results into a collection limited to a set figure
   FETCH cursor_name BULK COLLECT INTO table
   LIMIT 1000;

   -- For every record in the collection
   FORALL x IN INDICES OF table
      INSERT INTO target_table
      (col)
      VALUES
      table(x);

   -- Set up the limit loop exit criteria
   EXIT WHEN table.COUNT < 1000; -- Less that the limit you set    
-- End the loop
END LOOP;
-- Close the cursor
CLOSE cursor_name;