首先,创建测试表跟踪表
create table LIST_OF_CHANGES
(
TNAME VARCHAR2(30),
CNAME VARCHAR2(30),
CHANGED DATE
);
其次,创建RUN_DDL过程,用于在一张表中新增加一列
create or replace procedure RUN_DDL(m varchar2)
is
begin
execute immediate m;
end;
/
创建测试过程
create or replace procedure ADD_COLUMN(p_table varchar2,p_column varchar2) is
v number;
begin
insert into list_of_changes values(p_table,p_column,sysdate);
run_ddl('alter table '||p_table||' add '|| p_column);
v:=1/0; ----用于产生一个error,rolls back insert
end;
/
最后,执行 exec ADD_COLUMN('t','NEWCOL NUMBER'); ---t为随意创建的一张测试表
执行之后,会提示出错。
查看结果:
SQL> select * from list_of_changes;
TNAME CNAME CHANGED
------------------------------ ------------------------------ -----------
t newcol number 2010-4-21 17:19:03
------说明:产出跟踪记录
SQL> desc t
Name Type Nullable Default Comments
------ ---------- -------- ------- --------
A NUMBER(10) Y
B NUMBER(10) Y
C NUMBER(10) Y
D NUMBER(10) Y
NEWCOL NUMBER Y
------说明:新列已添加进去
解释:由于run_ddl中执行的为ddl语句,成功之后,就会自动带有commit效果,所以一同将insert操作commit。
之后将run_ddl过程修改为自治事务,如下:
create or replace procedure RUN_DDL(m varchar2)
is pragma autonomous_transaction;
begin
execute immediate m;
end;
/
再次重新执行ADD_COLUMN过程:
SQL> exec ADD_COLUMN('t','newcol2 number');
begin ADD_COLUMN('t','newcol2 number'); end;
ORA-01476: 除数为 0
ORA-06512: 在"SCOTT.ADD_COLUMN", line 6
ORA-06512: 在line 1
SQL> select * from list_of_changes;
TNAME CNAME CHANGED
------------------------------ ------------------------------ -----------
t newcol number 2010-4-21 17:19:03
-----说明:没有产生跟踪记录
SQL> desc t
Name Type Nullable Default Comments
------- ---------- -------- ------- --------
A NUMBER(10) Y
B NUMBER(10) Y
C NUMBER(10) Y
D NUMBER(10) Y
NEWCOL NUMBER Y
NEWCOL2 NUMBER Y
-------说明:新增加的列添加成功。
解释:自治事务不依赖于父事务,即定义为自治的过程无法成为父事务的一部分。