drop这样的ddl语句一定会隐式提交吗?

[复制链接]
查看11 | 回复7 | 2007-10-20 08:38:44 | 显示全部楼层 |阅读模式
oracle11.1.0.6版本下测试:
情况一:
SQL> select * from test;
ID
----------
1
3
2
4
5
SQL> delete from test where id=5;
已删除 1 行。
SQL> drop tableb;
drop tableb

*
第 1 行出现错误:
ORA-00942: 表或视图不存在
打开另一个窗口,查询test表得:
SQL> select * from test;
ID
----------
1
3
2
4
说明drop table b这句ddl语句虽然没有执行成功,但ddl隐式提交了,由于delete语句在它之前,所以也一并提交了。

情况二:
SQL> select * from test;
ID
----------
1
3
2
4
SQL> delete from test where id=3;
已删除 1 行。
SQL> drop table b';
drop table b'

*
第 1 行出现错误:
ORA-01756: 引号内的字符串没有正确结束
打开另一个窗口,查询test表得:
SQL> select * from test;
ID
----------
1
3
2
4
说明此时的drop DDL语句根本没有提交,同样的drop DDL语句为什么一个提交,一个没有提交呢?
[ 本帖最后由 lovelele 于 2009-8-12 15:08 编辑 ]
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
说明了语法解析成功后就开始做commit,之后才语义分析
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
Oracle中DDL语句对事务的影响
在Oracle中,执行DDL语句(如Create Table、Create View等)时,会在执行之前自动发出一个Commit命令,并在随后发出一个Commit或者Rollback命令,也就是说,DDL会象如下伪码一样执行:
Commit;
DDL_Statement;
If (Error) then
Rollback;
Else
Commit;
End if;
--上面这段话的含义是只要是执行ddl就一定隐式提交,因为在它解析之前,就先commit了呢
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
解析都没有通过,怎么会知道执行的是DDL呢
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层


对!
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
说到ddl的commit,就要说到隐式提交,隐式提交可能发生在
1. 正常退出sqlplus
2.ddl
3.dcl
一个ddl语句,比如说truncate操作,那么这个操作到底具体是如何执行的,一个ddl操作大致可以分解成
1.commit
2.truncate
3.commit
这3个操作不是原子操作,很容易证明这个问题
session 1:
SQL> create table test(id int) ;
表已创建。
SQL> insert into test select rownum from dual connect by rownum commit;
提交完成。
SQL> delete from test where rownum delete from test where rownum truncate table test;
truncate table test

*
第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源
session 3:
SQL> select * from test;
ID
----------
4
5
6
7
8
9
从session 3:的结果证明,session1的commit已经完成
整个语句的流程 :
truncate table test 之后
先是commit, 这时候session1的事务已经提交,由于session2 先发出的delete 语句,所以session2先执行,这时候又轮到session 1 ,因为session2 的事务没结束,所以session 1报错资源忙
转到正题,ddl的commit到底是何时执行的呢
session 1:
SQL> insert into test values(2);
已创建 1 行。
SQL> create table ;
create table

*
第 1 行出现错误:
ORA-00903: 表名无效
SQL> create table k;
create table k

*
第 1 行出现错误:
ORA-00906: 缺失左括号
SQL>create table k();
create table k()

*
第 1 行出现错误:
ORA-00904: : 标识符无效
SQL> create table tk(t chra(10));
create table tk(t chra(10))

*
第 1 行出现错误:
ORA-00907: 缺失右括号
SQL>create table tk(t nmuber);//我发现只有在这一步的时候才会被提交
create table tk(t nmuber)

*
第 1 行出现错误:
ORA-00902: 无效数据类型

SQL> select * from test;
ID
----------
1
2
session 2:
SQL> select * from test;
ID
----------
1
2
我把提交之前的所有错误归结为语法错误,而提交的那个错误则是语义错误
我对整个ddl操作过程的总结,先是进行语法分析,commit ,语义分析,ddl语句,commit

我2年前测试的
回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层

这个例子充分的说明了一个道理: 在存储过程中, 一定要慎用DDL语句, 否则一不留神, 连死都不知是如何死的!



回复

使用道具 举报

千问 | 2007-10-20 08:38:44 | 显示全部楼层
session 1:
SQL> create table test(id int) ;
表已创建。
SQL> insert into test select rownum from dual connect by rownum commit;
提交完成。
SQL> delete from test where rownum delete from test where rownum truncate table test; 它才能执行
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行