操作Oracle执行SQL语句老是出错,高手来看看杂回事?
1、Delphi操作Oracle,如果出现错误则执行紧跟着的下一条语句时就会弹出“A User transaction is already in progress”而无法执行
例如:
Query:=TQuery.Create(nil);
Query.DatabaseName:=self.db.DatabaseName;
Query.SQL.Clear;
Query.SQL.add('SELECT * FROM USERLIST');
try
Query.Open; //出错,因为这个表此刻不存在
except
end;
Query.Close;
Query.Free;
Query:=nil;
TmpTable.Active := False;
TmpTable.TableName := 'USERS';
TmpTable.TableType := ttDefault;
with TmpTable.FieldDefs do
begin
Clear;
Add('CODE'), ftString, 20, True);
Add('NAME', ftString, 40, False);
.....
Add('MS'),ftstring,60,false);
end;
TmpTable.IndexDefs.Clear;
TmpTable.IndexDefs.Add('IDX_'+'USERS', ('CODE'), [ixPrimary, ixUnique]);
try
TmpTable.CreateTable; //如果前面出错,此处也会出错提示“A User transaction is already in progress”
except on EDBEngineError do begin
ShowMessage('用户表创建错!');
end;
TmpTable.Active := False;
TmpTable.TableName := 'GROUP';
TmpTable.TableType := ttDefault;
with TmpTable.FieldDefs do
begin
Clear;
Add('CODE'), ftString, 20, True);
Add('NAME', ftString, 40, False);
.....
Add('MS'),ftstring,60,false);
end;
TmpTable.IndexDefs.Clear;
TmpTable.IndexDefs.Add('IDX_'+'GROUP', ('CODE'), [ixPrimary, ixUnique]);
try
TmpTable.CreateTable; //此处也不会出错
except on EDBEngineError do begin
ShowMessage('用户组创建错!');
end;
环境:win2000pro+Delphi6+Oracle8i
问题点数:100、回复次数:15Top
1 楼jinjazz(近身剪)回复于 2005-02-24 15:36:44 得分 0
你到底想说明什么问题呢?Top
2 楼78hgdong(赤脚)回复于 2005-02-24 15:40:09 得分 5
关注下去.Top
3 楼flyingwheat()回复于 2005-02-24 17:07:04 得分 0
不好意思,我的意思是:
第一次,执行了一条语句'SELECT * FROM 表名'判断数据库中是否存在表如果不存在就创建表。如果这个表不存在,则肯定报错。
第二次,执行了创建表语句 TmpTable.CreateTable; 但是可能是因为第一次的原因他每次报错“A User transaction is already in progress”。
第三次,执行同样的创建表语句 TmpTable.CreateTable,创建另外一个表,但是却没有出错。
我贴的代码也是这个意思。不知道如何解决这个问题,是Oracle没有设置好还是BDE没有设置好呢?
Top
4 楼czx0514(不想再做那份工作)回复于 2005-02-24 17:10:12 得分 15
这个问题应该是你在程序中写了数据库事务管理之类的代码,出错时你也没有相关的出错保护机制,事务没有及时的回滚或提交,报错是必然的。但是你这里是简单的查询应该不会有事务管理的说法,不懂你的代码是如何实现的。。。。Top
5 楼chaozhiping(晁智平)回复于 2005-02-24 17:14:16 得分 15
那有可能是因为你第一次提交查询的时候并没有处理事务,最好在是出错时回滚,Top
6 楼jinjazz(近身剪)回复于 2005-02-24 17:15:52 得分 15
//oracle的表信息都在TABLE_NAME中~~~判断表是否存在
Query.Close;
Query.SQL.Clear;
Query.SQL.add('select * from all_tables where TABLE_NAME=''USERLIST''');
Query.Open;
if Query.RecordCount>0 then //表存在Top
7 楼flyingwheat()回复于 2005-02-25 10:14:34 得分 0
谢谢大家的关注!
如果是没有处理好事务,如何在出错说回滚呢?
我刚开始学习Oracle,现在任务是看代码顺便学习Oracle。Top
8 楼jinjazz(近身剪)回复于 2005-02-25 10:22:04 得分 10
没有你那么判断表是否存在的~~
学oracle就脱离开发语言,搞懂pl/sql语法Top
9 楼flyingwheat()回复于 2005-02-25 10:44:06 得分 0
谢谢关注!
为什么不可以这样判断,这样判断也可以啊。只要到达目的就行啊,为什么要中规中局的?任何人都有访问“all_tables”这个表吗?Top
10 楼Kshape(C/C++初学者~~~~)回复于 2005-02-25 11:06:48 得分 25
事务操作,看看下面例子
Database1.StartTransaction
with Query do
begin
Sql.clear
Sql.Add(str1);
Sql.Add(str2);
Try
ExecSql;
//扑获异常
if DataBase1.Errors.Count = 0 then
Database1.Commit; //成功,事务提交
else
Database1.Rollback; //失败,事务回滚
Except
Database1.Rollback; //失败,事务回滚
End;
end;
Top
11 楼flyingwheat()回复于 2005-02-25 12:22:05 得分 0
谢谢关注Top
12 楼jinjazz(近身剪)回复于 2005-02-25 12:23:37 得分 10
>>任何人都有访问“all_tables”这个表吗?
那你设计数据库时可以做视图,授权给任何人Top
13 楼flyingwheat()回复于 2005-02-26 11:31:08 得分 0
结果:BDE参数设置错误SQLPASSTHRU MODE:SHARED AUTOCOMMIT
Dephi帮助如下:
SQLPASSTHRU MODE settings
This parameter determines whether and how passthrough SQL and standard BDE calls share the same database connections. For transactions, this translates to whether passthrough transactions and other transactions "know" about each other.
Only applications that use passthrough SQL need be concerned with SQLPASSTHRUMODE. If you are developing an application to control transactions with passthrough SQL, you must set SQLPASSTHRU MODE to NOT SHARED. Otherwise passthrough SQL and the application's methods may interfere with each other, leading to unpredictable results.
Setting Meaning
NOT SHARED
(blank setting) Passthrough SQL and non-passthrough SQL do NOT share the same database connection.
SHARED AUTOCOMMIT
Passthrough SQL and non-passthrough SQL will share the same connection, and (as long as you are not in an explicit client transaction or batch mode) passthrough SQL will be automatically committed. Each operation on a single row is committed. This mode most closely approximates desktop database behavior but it is inefficient on SQL servers because it starts and commits a new transaction for each row, resulting in a heavy load of network traffic.
SHARED NOAUTOCOMMIT
Passthrough SQL and non-passthrough SQL share the same connection, but passthrough statements will not be automatically committed. The application must explicitly start and commit transactions. This setting could result in conflicts in busy multi-user environments where many users are updating the same rows.Top
14 楼flyingwheat()回复于 2005-02-26 11:34:20 得分 0
至于为什么这样写SQL是因为这个程序在SQL和Oralce下代码基本一样的,所以不能象“jinjazz(近身剪(N-P攻略))”老兄所说的那样写代码。
最后再次感谢大家的关注!
Top
15 楼caiso(十年磨一剑)回复于 2005-02-26 13:47:05 得分 5
顶一下Top




