如何使用BULK_COLLECT而不是insert into select

时间:2013-10-31 21:39:50

标签: sql oracle plsql

我一直在网上搜索,我惊讶地发现每个地方都有相同的例子,并且总是all_objects。在高级SQL方面不太好,我不明白如何将此语句转换为使用BULK_COLLECT。

INSERT INTO bpm_staging ( 
    id, pay_obj, merchant, address,
    city, country,debit_num, first_name,
    state, zip, id_type,bank_no)
  SELECT 
    p.account_obj, p.id, p.ach, pc.address,
    pc.city, pc.country, pc.debit_num, pc.name,
    pc.state, pc.zip, p.id_type,pc.bank_no
  FROM au_pay_t p, au_pay_dd_t pc 
  WHERE p.id= pc.obj;

我使用了上述语句,因为使用游标需要更长时间。对于必须修改查询的任何人来说,使用Select也更容易理解。

但是,我的DBA拒绝在Production上运行,因为这将花费很长时间来逐行插入540K记录。

当我在网上搜索时,我发现BULK_COLLECT / FORALL是更好的选择,因为性能方面。

请建议更好的解决方法。如果BULK_COLLECT是一个不错的选择,那么请提出一个很好的例子。

2 个答案:

答案 0 :(得分:1)

  1. 定义适当的PL / SQL类型(记录类型和嵌套表类型)以收集结果:

    TYPE my_type IS RECORD (
        account_obj au_pay_t.account_obj%TYPE,
        id          au_pay_t.id%TYPE,
        /* ... */
        bank_no     au_pay_dd_t.bank_no%TYPE
    );
    
    TYPE my_tab_type IS TABLE OF my_type;
    
  2. 使用上面定义的嵌套表类型声明PL / SQL变量:

    DECLARE
      my_tab my_tab_type;
    
  3. 使用您的变量存储查询结果:

    SELECT
      p.account_obj, p.id, p.ach, pc.address,
      pc.city, pc.country, pc.debit_num, pc.name,
      pc.state, pc.zip, p.id_type,pc.bank_no
    BULK COLLECT INTO my_tab
    FROM au_pay_t p, au_pay_dd_t pc
    WHERE p.id = pc.obj;
    
  4. 最后,循环结果以将它们插入表格

    FORALL i IN 1..my_tab.COUNT
      INSERT INTO bpm_staging ( 
          id, pay_obj, merchant, address,
          city, country,debit_num, first_name,
          state, zip, id_type,bank_no)
      VALUES (
          my_tab(i).account_obj, my_tab(i).id,
          ..., my_tab(i).bank_no);
    
    • 警告:上述构造仅适用于Oracle 11g或更高版本

答案 1 :(得分:0)

insert /*+ append */ into

也可能加快速度。