6

我在使用 PL/SQL 向 Oracle 表中进行大量插入时遇到问题。我的查询逐行进行,查询对每一行进行计算以确定它需要插入另一个表的行数。传统的插入工作,但代码需要很长时间才能运行大量行。为了加快插入速度,我尝试使用Append_Values以下示例中的提示:

BEGIN
FOR iter in 1..100 LOOP
INSERT /*+ APPEND_VALUES*/ INTO test_append_value_hint values (iter);
END LOOP;
END;

执行此操作时,我收到以下错误消息:

ORA-12838: cannot read/modify an object after modifying it in parallel
ORA-06512: at line 3
12838. 00000 -  "cannot read/modify an object after modifying it in parallel"
*Cause:    Within the same transaction, an attempt was made to add read or
           modification statements on a table after it had been modified in parallel
           or with direct load. This is not permitted.
*Action:   Rewrite the transaction, or break it up into two transactions
           one containing the initial modification and the second containing the
           parallel modification operation.

有没有人知道如何使这段代码工作,或者如何快速将大量行插入另一个表?

4

3 回答 3

4

您收到此错误是因为您的每个 INSERT 都作为单独的 DML 语句执行。Oracle 在提交之前阻止对使用直接路径插入添加数据的表进行读/写。从技术上讲,您可以使用 PL/SQL 集合和 FORALL 代替:

SQL> declare
  2   type array_t is table of number index by pls_integer;
  3   a_t array_t;
  4  begin
  5    for i in 1..100 loop
  6      a_t(i) := i;
  7    end loop;
  8    forall i in 1..100
  9      insert /*+ append_values */ into t values (a_t(i));
 10  end;
 11  /

但是贾斯汀提出的问题是实际的——你的数据来自哪里,为什么你不能使用通常的 INSERT /*+ append */ INTO ... SELECT FROM 方法?

于 2014-02-15T08:43:23.560 回答
3

嗨请求您在插入后使用提交,如下所示:

BEGIN
FOR iter in 1..100 LOOP
INSERT /*+ APPEND_VALUES*/ INTO test_append_value_hint values (iter);
COMMIT;
END LOOP;
END;
于 2015-03-28T17:31:36.633 回答
1

如果不提交第一个事务,我们就无法在一个表中执行 2 个 DML 事务。因此将引发此错误。

因此,在该表中提交您之前的事务并继续第二个事务。

于 2017-10-11T09:45:12.167 回答