PLSQL中的批量插入而不是循环?

Posted

技术标签:

【中文标题】PLSQL中的批量插入而不是循环?【英文标题】:Bulk insert instead of loop in PLSQL? 【发布时间】:2012-01-17 19:28:24 【问题描述】:

我正在尝试使用批量插入或其他更有效的方法来解决这段代码,但我没有想法。你会如何处理这个问题。而不是循环这么多次,我想在几个电话中更有效地做到这一点。请让我知道你会怎么做?如果可能的话,用代码!谢谢

LOOP
-- Fetch a row
IF DBMS_SQL.FETCH_ROWS(cursor_handle) > 0 THEN
    DBMS_SQL.column_value(cursor_handle, 9, cont_id); 
    DBMS_SQL.COLUMN_VALUE(cursor_handle, 3, proj_nr);  
    HTP.BOLD('ContractID: ' || cont_id || ' ProjectNR: ' ||  proj_nr);
    HTP.BR;
ELSE
    EXIT;
END IF;

-- delete the old list before saving a new one
IF sek_nr = 1 THEN
  EXECUTE IMMEDIATE 'DELETE FROM W_Contracts WHERE user_id = :n' USING CURRENTUSER;
END IF;

EXECUTE IMMEDIATE 'Insert into W_Contracts values(''' || currentUser || ''', '
                   || sek_nr || ', sysdate, ' || cont_id || ', '''
                   || proj_nr || ''')';

sek_nr := sek_nr + 1;
END LOOP;

【问题讨论】:

【参考方案1】:

首先,我不清楚您为什么使用动态 SQL 而不是静态 SQL。

IF sek_nr = 1 
THEN
  DELETE FROM w_contracts
   WHERE user_id = currentUser;
END IF;

INSERT INTO w_contracts( <<list of columns>> )
  VALUES( currentUser, sek_nr, sysdate, cont_id, proj_nr );

接下来,如果 SEK_NR 为 1,我不清楚为什么您可能会先执行 DELETE,然后再执行 INSERT。在这种情况下执行 UPDATE 可能会更有效。而且,一旦您执行了 UPDATEINSERT,您就可以将其简化为单个 MERGE 语句。

接下来,如果您在DBMS_SQL 中使用DEFINE_ARRAY method,您可以从光标中批量提取数据。当然,如果没有看到您的游标定义,我会怀疑它也不必要地使用了动态 SQL,您可以使用更简单的方法。

【讨论】:

感谢贾斯汀的回答。您对动态 sql 部分是正确的。我将尝试解释其余的代码。由于不能保证 sek_nr = 1 我每次在我的循环中都检查它,这不是我猜的最佳解决方案。但是如果 sek_nr 是 1 我只想从 w_contracts 表中删除一个条目。此后,我继续我的插入,我知道这是一个性能问题。以其他方式解决这个问题会更有效,比如批量插入或其他方式。你对如何做到这一点有任何想法吗?感谢您的帮助!

以上是关于PLSQL中的批量插入而不是循环?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Laravel 4.2 在单个查询(不是 for 查询循环)中批量插入或更新

Azure SQL - 从 Azure 文件而不是 Blob 批量插入

数据库批量插入这么讲究的么?

Yii2中的Active Record可以批量插入数据吗

如何强制 django 立即保存而不是在循环后进行批量更新

mybatis批量插入,然后获取每个对象自增的id,怎么实现啊