游标中使用动态的sql 语句能造成死循环 (我已经解决提出来给大家看看.不知道大家遇到没有 )

10975037 2005-08-12 02:35:38
小弟在作一个系统.非的要用游标中使用动态的sql 才可以满足要求.但出现死循环 .开始不解 后来发现的用 两个事务才能解决. 我用的是一个默认的sqlca .和 SQLCA_MASTER 这就是要在连接数据库是多建立一个事务

例如 默认是 sqlca 事务
sqlca.DBMS = ProfileString (ls_startupfile, "database", "dbms", "")
sqlca.database = ProfileString (ls_startupfile, "database", "database", "")
sqlca.userid = ProfileString (ls_startupfile, "database", "userid", "")
sqlca.dbpass = ProfileString (ls_startupfile, "database", "dbpass", "")
sqlca.logid = ProfileString (ls_startupfile, "database", "logid", "")
sqlca.logpass = ProfileString (ls_startupfile, "database", "Logpass", "")
sqlca.servername = ProfileString (ls_startupfile, "database", "servername", "")
sqlca.dbparm = ProfileString (ls_startupfile, "database", "dbparm", "")
在建立一个 SQLCA_MASTER 事务
transaction sqlca_master

sqlca_master.DBMS = ProfileString (ls_startupfile, "database", "dbms", "")
.......

// 游标
declare ffx_or_kkx cursor for
select distinct fld_name, fld_chin_name,fld_pay from DICT_ALL_COLUMN
WHERE TABLE_NAME =:is_table_name and ( fld_pay='2' ) and ( fld_type ='decimal');
open ffx_or_kkx;
my_sql = "insert into grsr() values ()"

execute immediate :my_sql using sqlca ; // 换成sqlca_master 就不会死循环



do while sqlca.sqlcode = 0

fetch ffx_or_kkx into :get_fld_name,:get_fld_chin_name,:get_fld_pay;
my_sql = "insert into grsr() values ()"
execute immediate :my_sql using sqlca; //// 换成sqlca_master 就不会死循环


messagebox('',string (sqlca.sqlcode))

loop
close ffx_or_kkx;

不知道大家遇到没有 ,可以试试看 . 为什么呢 /
因为游标是 sqlca.sqlcode = 0 就循环. 而用 动态的sql 执行成功后.返回sqlca.sqlcode 是0 这样破使你的事务总是0 就是sqlca.sqlcode 总是0 . 所以是死循环 .


不知道大家明白没有 . 可以试试看
...全文
400 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
geshutiancg 2005-08-13
  • 打赏
  • 举报
回复
study…………
guxing 2005-08-13
  • 打赏
  • 举报
回复
因为游标是 sqlca.sqlcode = 0 就循环. 而用 动态的sql 执行成功后.返回sqlca.sqlcode 是0 这样破使你的事务总是0 就是sqlca.sqlcode 总是0 . 所以是死循环

难道你不会用一个变量来记录吗?
Long ll_DbCode_Cur , ll_DbCode_Sql

ll_DbCode_Cur = Sqlca.SqlCode //游标
...
ll_DbCode_Sql = Sqlca.SqlCode //游标
//判断


iwl 2005-08-13
  • 打赏
  • 举报
回复
当然是死循环了
execute immediate :my_sql using sqlca;
这句已经把原来的FECTCH的SQLCODE的值覆盖了,只要这句执行正常那么SQLCODE就会=0,然后返回到while处.
lzheng2001 2005-08-12
  • 打赏
  • 举报
回复
这么明显的错误还用讨论吗,改用两个事务吧
或者调一下语句的位置就行了,把
execute immediate :my_sql using sqlca;
放到fetch 语句之前执行就可以了
10975037 2005-08-12
  • 打赏
  • 举报
回复
楼上的 如果你的动态的 sql 语句执行成功
my_sql = "insert into grsr() values ()"
execute immediate :my_sql using sqlca;
你的 sqlca.sqlcode 始终是0 的 怎么能跳出来 能.

if sqlca.sqlcode <> 0 then exit 这句话又有什么意义能 ?

欢迎大家讨论
零上三度 2005-08-12
  • 打赏
  • 举报
回复
万分敬佩楼上的
我是真心话,像楼上如此认真分析,着实让我佩服
hillhx 2005-08-12
  • 打赏
  • 举报
回复
**我觉得你创建sqlca_master就是多余的,光sqlca就够了
**关键问题是你没理解sqlcode属性的意义
**sqlcode的属性的意义是某个数据库连接对象上次执行的SQL语句所返回的系统值 -1 错误 0 成功 100 游标到底
**下面就分析分析你这个程序每句执行后的sqlcode 值

execute immediate :my_sql using sqlca;
//如果你的游标定义的正确的话,此时sqlca.sqlcode = 0

do while sqlca.sqlcode = 0
//
fetch ffx_or_kkx into :get_fld_name,:get_fld_chin_name,:get_fld_pay;
//如果游标有值,此时sqlca.sqlcode = 0 如果游标没值 此时sqlca.sqlcode = 100

my_sql = "insert into grsr() values ()"
execute immediate :my_sql using sqlca;
//如果execute成功sqlca.sqlcode = 0 否则sqlca.sqlcode = -1
//当sqlca.sqlcode = 0 的时候正好又满足循环的条件再次进入循环虽然FETCH的时候返回了100,
//但因为execute总能成功插入值所以sqlca.sqlcode又变成了0,所以就造成了死循环

messagebox('',string (sqlca.sqlcode))
loop

将程序改为,但是就算这么改你的程序的结构还是不很好,最好每次执行完SQL语句都判断sqlcode的值如果失败一定要回滚

execute immediate :my_sql using sqlca;
//如果你的游标定义的正确的话,此时sqlca.sqlcode = 0

do while sqlca.sqlcode = 0
//
fetch ffx_or_kkx into :get_fld_name,:get_fld_chin_name,:get_fld_pay;

//如果游标到底直接退出
if sqlca.sqlcode <> 0 then exit

my_sql = "insert into grsr() values ()"
execute immediate :my_sql using sqlca;
//如果失败回滚
if sqlca.sqlcode <> 0 then rollback using sqlca;

messagebox('',string (sqlca.sqlcode))
loop
lzheng2001 2005-08-12
  • 打赏
  • 举报
回复
当然是死循环了
execute immediate :my_sql using sqlca;
这句已经把原来的FECTCH的SQLCODE的值覆盖了,只要这句执行正常那么SQLCODE就会=0,然后返回到while处.



yl_yz 2005-08-12
  • 打赏
  • 举报
回复
还没这样用过,谢楼主
saiche05 2005-08-12
  • 打赏
  • 举报
回复
改为这样看看:
open ffx_or_kkx;
my_sql = "insert into grsr() values ()"


do while sqlca.sqlcode = 0
execute immediate :my_sql using sqlca ;
fetch ffx_or_kkx into :get_fld_name,:get_fld_chin_name,:get_fld_pay;
my_sql = "insert into grsr() values ()"
//execute immediate :my_sql using sqlca;


loop
close ffx_or_kkx;

1,079

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 相关问题讨论
社区管理员
  • 基础类社区
  • WorldMobile
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧