使用动态sql进行所有插入

使用动态sql进行所有插入,sql,oracle,plsql,Sql,Oracle,Plsql,我有一组insert命令存储在表类型变量(varchar2)中。这些记录被插入到同一表的相同列中 如何编写forall循环来执行这些插入查询 谢谢,您可以在嵌套表上循环,如下例所示(从) 您可以通过构造运行动态创建的查询 也就是说,您的问题可以通过以下示例代码解决 declare type table_varchar is table of varchar2(4000); tv_inserts table_varchar := table_varchar(); begin

我有一组insert命令存储在表类型变量(varchar2)中。这些记录被插入到同一表的相同列中

如何编写forall循环来执行这些插入查询


谢谢,您可以在嵌套表上循环,如下例所示(从)

您可以通过构造运行动态创建的查询

也就是说,您的问题可以通过以下示例代码解决

declare
    type table_varchar is table of varchar2(4000);
    tv_inserts table_varchar := table_varchar();
begin
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := 'insert into test_table(col1, col2) values(1, 10)';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := 'insert into test_table(col1, col2) values(2, 20)';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := 'insert into test_table(col1, col2) values(3, 30)';

    for ind in tv_inserts.first..tv_inserts.last
    loop
        execute immediate tv_inserts(ind);
    end loop;
end;
可以与execute immediate一起使用,但如下例所示

declare
    type table_varchar is table of varchar2(4000);
    tv_inserts table_varchar := table_varchar();
begin
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '1';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '2';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '3';

    for ind in tv_inserts.first..tv_inserts.last
    loop
        execute immediate 'insert into test_table(col1) values(:a)'
            using tv_inserts(ind);
    end loop;
end;

请注意,如果不事先处理输入数组,这种方法是不可行的。

您有一个要执行的SQL命令字符串?是的,包含insert命令的字符串数组。在我当前的代码中,我所做的正是您编写的。性能是这里的问题,我需要使用forall一次插入所有内容,这可能吗?我已经用您的澄清更新了答案。我建议您编辑您的问题,添加一段您尝试过的代码,并解释您遇到的性能问题,否则此问题可能会被删除。FORALL当然是一种方法。这并不意味着你“一次插入所有内容”。这意味着N条insert语句将通过一个上下文开关传递给SQL引擎进行处理。如果您能找到一种使用SQL INSERT语句(如INSERT-SELECT)而不是FORALL来完成所有这些操作的方法,那么它可能会运行得更快。但一定要仔细考虑这个问题的错误处理。是全部还是全部?如果插入1000行,然后第1001行导致错误,是否保留前1000行?在本例中,包括保存异常。我的博客文章可能会在这里有所帮助:谢谢,但是这些值是以字符串格式存储的。由逗号分隔,我想我必须将每个值拆分为一个数组,然后尝试全部。
declare
    type table_varchar is table of varchar2(4000);
    tv_inserts table_varchar := table_varchar();
begin
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '1';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '2';
    tv_inserts.extend();
    tv_inserts(tv_inserts.count) := '3';

    for ind in tv_inserts.first..tv_inserts.last
    loop
        execute immediate 'insert into test_table(col1) values(:a)'
            using tv_inserts(ind);
    end loop;
end;