2

oracle 中是否有用于自动提交的内置功能?就像如果我想更新一百万行,并且我想将自动提交设置为 1000 行或 2000 行,我必须在某个地方进行配置。
它将在每 1000 或 2000 行之后使用自动提交更新循环中的百万行。此功能在 sqlloader 中可用。我想知道 oracle 中是否也有类似的功能。

4

3 回答 3

7

不可以。您不能要求 Oracle 以增量方式提交单个 SQL 语句正在执行的工作。这将违反 ACID 合规性的原子性部分,因此对于关系数据库来说,这将是一件非常糟糕的事情。这样做意味着如果数据库失败或语句在处理 N 行后失败,您将无法知道哪些 N 行已被处理。这样做意味着其他用户可能会看到部分完整的数据,从而导致他们的报告不正确,并且他们的查询可能会返回误导性结果。

当然,您可以编写自己的自定义逻辑来批量更新行。然而,这通常是一个坏主意。运行正在执行临时提交的进程将需要更长的时间,甚至可能更长的时间。它将需要编写代码以确保该过程是可重入的(也就是说,它可以在服务器故障的情况下从中断的地方继续,而无需尝试重​​新更新已经更新和提交的行或至少不要将数据更新为不同的值。这将导致更新在服务器UNDO上生成更多REDO。这将要求使用数据的每个进程都知道他们可能在处理过程中读取它UPDATE陈述。而且它增加了 ORA-01555 错误的风险。通常不需要临时提交——缺点是非常非常少值得的。

于 2012-10-25T02:44:41.370 回答
1

是的。您可以使用DBMS_PARALLEL_EXECUTE执行此操作。

该包显然是为了并行执行事物,但它也在每个“块”之后提交。您可以将 设置chunk_size为 1000 或 2000 行,并将 设置parallel_level为 0 以串行运行。

这是一个简单的例子:

create table table1(a number);
insert into table1 select level from dual connect by level <= 100000;
commit;

begin
    dbms_parallel_execute.create_task('update_table1');

    dbms_parallel_execute.create_chunks_by_rowid(
        task_name => 'update_table1',
        table_owner => user,
        table_name => 'TABLE1',
        by_row => true,
        chunk_size => 1000
    );

    dbms_parallel_execute.run_task(
        task_name => 'update_table1',
        sql_stmt => 'update table1 set a = 5 where rowid between :start_id and :end_id',
        language_flag => dbms_sql.native,
        parallel_level => 0);
end;
/

尝试中途终止查询或会话。您只能看到部分更改已提交,并且您可以使用 跟踪块状态dba_parallel_execute_chunks


但是,我同意 Justin Cave 和 Wolf 的观点,即这个功能几乎总是一个坏主意。

于 2012-10-25T06:24:48.787 回答
-3

语法 AUTOCOMMIT { ON | OFF } 描述 打开或关闭连接的自动提交模式。JDBC 指定默认的自动提交模式为 ON。某些类型的处理需要关闭自动提交模式。有关自动提交的信息,请参阅 Java DB Developer's Guide。

如果在有未完成的事务时将自动提交模式从关闭更改为打开,则在当前事务提交时提交该工作,而不是在打开自动提交时提交。当有事务未完成时,在打开自动提交之前使用 Commit 或 Rollback,以便在返回自动提交模式之前完成所有先前的工作。

Example
ij> autocommit off;
ij> DROP TABLE menu;
0 rows inserted/updated/deleted 
ij> CREATE TABLE menu (course CHAR(10), item CHAR(20), price INT);
0 rows inserted/updated/deleted
ij> INSERT INTO menu VALUES ('entree', 'lamb chop', 14),
('dessert', 'creme brulee', 6), 
('appetizer', 'baby greens', 7); 
3 rows inserted/updated/deleted
ij> commit;
ij> autocommit on;
ij>
于 2012-10-25T02:13:15.997 回答