我想在存储过程中实现这样一段代码:
用事务实现,第一句SQL 把A 表更名为C表,
                 第二句SQL再把B表更名为A表。
这两句要么一起实现,要么都回滚。
问题:
1,可是ORACEL的DDL是自动提交的,就是说‘第一句把A 表更名为C表’执行后 就提交了,这可怎么办?
2,在存储过程中的DDL都是用execute immediate '......'吗?有别的方式吗?

解决方案 »

  1.   

    ddl命令不能回滚
    在存储过程中只能用execute immediate动态完成
    在异常处理中,若第二句失败,将C表更名回A表?
      

  2.   

    ORACLE的一个事务是以第一个可执行的SQL语句开始。当下列事件之一发生时结束。 1.        用户执行了COMMIT语句(提交)。 
    2.        用户执行了ROLLBACK语句(回滚)。 
    3.        用户执行了DDL语句(自动提交)。 
    4.        用户执行了DCL语句(自动提交)。 
    5.        用户正常退出SQL*PLUS(自动提交)。 
    6.        用户非正常退出SQL*PLUS(自动回滚)。 
    7.        系统崩溃,包括硬件或软件故障(自动回滚)。自己写个回滚功能啊,例如你要他回滚的时候表名改回就可以了,相当于实现了回滚在 Oracle 8i 及以上版本中,还能用 DBMS_UTILITY.EXEC_DDL_STATEMENT(ddl_sql_str) 执行 DDL 语句。Oracle 8i 以下版本相应解决之道,用 DBMS_SQL 包,如 Oracle 8.0.5 中
      

  3.   

    declare
      cflag integer;
      aflag integer;
    begin
      cflag := 0 ;   --默认执行c表重命名成功
      aflag :=0;
      -- 执行C表重命名
      begin
        execute immediate '';
      exception
        when others then
          cflag := 1;
      end;
      
      --重命名b表
      begin
        execute immediate '';
      exception
        when others then
          aflag := 1;
      end;  exception
      when others then
        if cflag = 1 then  -- 回滚c
        if aflag = 1 then  -- 回滚a
    end;
      

  4.   


    declare 
      cflag integer; 
      aflag integer; 
    begin 
      cflag := 0 ;  --默认执行c表重命名成功 
      aflag :=0; 
      -- 执行C表重命名 
      begin 
        execute immediate 'drop table mytable2'; 
      exception 
        when others then 
          cflag := 1; 
      end; 
      
      --重命名b表 
      begin 
        execute immediate 'drop table xxxxxxxxx'; 
      exception 
        when others then 
          aflag := 1; 
      end; 
    exception 
      when others THEN
        if cflag = 1 then  ROLLBACK; END IF;
        if aflag = 1 then  ROLLBACK; END IF;-- 回滚a 
    end;以上表xxxxxxxxx不存在,执行到这里的时候会报错,按照你的意思是回滚的,为什么我的表mytable2被删除了呢?
      

  5.   

       ddl命令不能回滚!