【问题标题】:Usage of BULK COLLECT and dbms_sqlBULK COLLECT 和 dbms_sql 的使用
【发布时间】:2012-04-23 20:45:02
【问题描述】:

我正在阅读有关 BULK COLLECT 和 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;

但是由于要插入另一个表的数据很大,在我的第二个修改过程中

我使用了 BULK COLLECT 和 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; 

所以这是我的第二个示例,但是我根据文档使用了 BULK collect

有人能指出dbms_sql.Varchar2_Table 的确切用法吗?

如上所示如果col1的实际长度是VARCHAR2(40)但是dbms_sql.Varchar2_Table使用VARCHAR2(2000)

TYPE varchar2_table IS TABLE OF VARCHAR2(2000) INDEX BY BINARY_INTEGER;

【问题讨论】:

  • 您的具体问题是什么?您提供的代码充满了语法错误。您应该提供您正在使用的确切来源,并说明您遇到的问题是什么
  • 我的问题是我在使用 BULK COLLECT 和使用 dbms_sql 插入另一个表的示例第二个中使用的方法是否正确。希望这很好。

标签: oracle oracle11g


【解决方案1】:

当您使用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;

这个伪代码 sn-p 应该让您开始正确的道路,让您的批量代码工作。您当前对 DBMS_SQL 表的声明看起来不错。

希望对你有帮助...

【讨论】:

  • 谢谢 我关于 dbms_sql 的问题如上所示,如果 col1 的实际长度是 VARCHAR2(40) 但 dbms_sql.Varchar2_Table 使用 VARCHAR2(2000) 并且根据 oracle 文档 varchar2_table 是 TYPE varchar2_table IS TABLE OF VARCHAR2 (2000) BINARY_INTEGER 索引;那么为什么实际长度为 40 时使用 2000 空间呢?
  • 这是一个方便的构造函数,可以快速有效地使用包含VARCHAR2 值的表。如果您真的担心 VARCHAR2(2000) 数组使用的额外字节,那么创建您自己的集合以使用最大长度为 40。TYPE array_40_chartype IS TABLE OF VARCHAR2(40) INDEX BY BINARY_INTEGER; 然后使用类型声明一个表:array_40_char array_40_chartype; 瞧。
  • 感谢 Ollie 在您的示例中 FETCH cursor_name BULK COLLECT INTO 表,这里的表是集合的一种类型吗?
  • 是的。这是一个集合。我通常使用关联数组来批量收集。
猜你喜欢
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多