【问题标题】:Batch process for oracle sqloracle sql的批处理
【发布时间】:2014-03-09 01:57:06
【问题描述】:

我正在使用以下查询将数据从一个表复制到同一数据库中的另一个表“insert into table select * from table where time_stamp

【问题讨论】:

  • 如果您需要复制整个表格,请尝试 CTAS(创建表格作为选择),然后一次性完成。

标签: sql oracle


【解决方案1】:

你为什么要这样做?它使过程更慢、更难编码、更难在发生错误时恢复。

除非您有特殊原因,否则只在最后提交。否则你必须编写 PL/SQL 来完成。

你的代码应该是:

insert into table
select *
from table
where time_stamp <= ADD_MONTHS(sysdate,-1);

【讨论】:

  • 该代码运行良好,但记录数以百万计,最好分批复制
  • @user3274312 - 为什么你认为分批做更好? (Here's an example of why Tom Kyte thinks it isn't,这与大卫所说的相呼应)。
  • 对于“百万”,我也会考虑直接路径插入,如果您可以在插入过程中锁定表格。
  • @user3274312 您预计会出现什么样的错误,如果发生任何错误,您将如何确定哪些记录已成功插入、识别问题记录并仅插入其他记录?您看过 Oracle 的日志错误功能吗?
  • @user3274312 - 如果在复制将回滚的批次时发生任何错误;你将如何从那个位置恢复?你不能只是重新启动,因为你会得到重复。如果您从下一批继续,您如何知道缺少哪些记录?似乎你只是让自己的生活变得更加艰难。您还可以查看error logging table,这样会跳过错误行,而不必回滚成功的行。
【解决方案2】:

这是您可以用来实现目标的 PL/SQL 块

declare
  cursor c is
    select *
    from tableName
    where time_stamp <= add_months(sysdate,-1);

  type tbl is table of c%rowtype;

  t     tbl;
begin
  open c;

  loop
    fetch c bulk collect into t limit 1000;

    exit when c%notfound;

    forall i in 1..t.count
    insert into tableName2 values t(i);

    commit;
  end loop;

  close c;
end;

很遗憾,我不知道你的专栏,所以你可以重写这部分

insert into tableName2 values t(i);

例如像这样

insert into tableName2(col1,col2) values t(i).col1,t(i).col2;

我没有测试过,但这更多是关于如何做的想法。

【讨论】:

  • SAVE EXCEPTIONS 附加到您的 FORALL 可能会捕获异常(约束)并继续下一个记录。否则它会在出现一个异常时停止。更多详情来自Oracle Docs
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 2018-09-18
  • 2020-06-28
  • 2011-06-19
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多