【问题标题】:How to rollback between two savepoints like scenario如何在两个保存点之间回滚,例如场景
【发布时间】:2013-08-15 18:42:27
【问题描述】:

我正在开发 oracle 11g。我对 oracle 完全陌生,但现在我需要编写一个存储过程。 在我的过程中,我正在删除表并插入表单暂存表。同时删除许多表具有完整性约束。如果我在插入父表后也删除所有子表,我需要回滚所有子表。

例如:

delete ch1,ch2,ch3;
delete parent;
insert into parent;
rollback ch1,ch2,ch3;

请给我一些解决方案,例如禁用/启用完整性约束或如何使我的交易对我的场景有价值。

【问题讨论】:

  • 你真的只是在刷新父表吗?如果刷新的数据缺少曾经存在并有子记录的记录会怎样?你可以search for how to disable constraints。如果您将删除/插入作为一个事务,您也可以使约束可延迟。
  • 谢谢 Alex。是的,正是我正在刷新父表,但始终刷新的数据不会错过这种情况。如果有任何代码 sn-p,它将有所帮助。
  • 该搜索中的first answer on the first question 具有禁用触发器的代码。您可能会更加严格并过滤以仅修改您的子表和外键('R')。尽管仅列出表和约束而不是使用动态 SQL 可能更容易,但这取决于有多少、它们可能更改的频率以及必须执行的频率。
  • 我有近 110 个表是一个父主键的子表。所以我需要禁用所有子外键,不需要父主键。我得到了我的答案 Alex 非常感谢。跨度>

标签: oracle oracle11g


【解决方案1】:

如果子表是静态的,那么您可以使用如下查询生成一个脚本来启用和禁用它们:

select 'alter table ' || fk.owner ||'.'|| fk.table_name
  ||' disable constraint '|| fk.constraint_name ||';'
from all_constraints fk
join all_constraints pk
on pk.owner = fk.r_owner
and pk.constraint_name = fk.r_constraint_name
where fk.constraint_type = 'R'
and fk.status = 'ENABLED'
and pk.constraint_type = 'P'
and pk.table_name = '<your parent table>;

这给出了可以在删除/插入之前运行的alter table 命令列表,您可以执行相同的操作来创建脚本以重新启用它们。

如果您想即时执行此操作,考虑到您想从存储过程中执行此操作,这更有可能执行此操作,您可以在游标中执行相同的操作并将其作为动态 SQL 执行:

begin
  for r in (
    select 'alter table ' || fk.owner ||'.'|| fk.table_name
      ||' disable constraint '|| fk.constraint_name as stmt
    from all_constraints fk
    join all_constraints pk
    on pk.owner = fk.r_owner
    and pk.constraint_name = fk.r_constraint_name
    where fk.constraint_type = 'R'
    and fk.status = 'ENABLED'
    and pk.constraint_type = 'P'
    and pk.table_name = 'T42'
    ) loop
    execute immediate r.stmt;
  end loop;
end;
/

SQL Fiddle demo of both options.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-04
    • 2019-09-05
    • 1970-01-01
    • 2014-04-26
    相关资源
    最近更新 更多