请看看我的游标哪儿错啦

时间:2021-10-23 19:41:31
DECLARE cs_th_daoru_zz CURSOR FOR  
 select th_ck.fgid,th_ck.quantity
   from th_ck 
 where th_ck.trantype='总装配送'
    and  th_ck.lastdate>:ldt_maxdatetime;
open cs_th_daoru_zz;
fetch cs_th_daoru_zz into   :ll_fgid,:ll_quantity;
do   while  sqlca.sqlcode=0
 select   th_zzonland.fgid
 into :ll_zzfgid
 from th_zzonland 
 where th_zzonland.fgid=:ll_fgid;
 if ll_zzfgid<>0 then
UPDATE th_zzonland  
     SET  th_zzonland.quantity =:ll_quantity //10// th_zzonland.quantity//+99// quantity+:ll_quantity  
   WHERE th_zzonland.fgid =:ll_fgid
;   
        commit;
fetch cs_th_daoru_zz into   :ll_fgid,:ll_quantity;

loop 
 close cs_th_daoru_zz;
我察看有记录5842条,但是只能取一条记录。sqlcode=-1 就退出。是什么原因???

11 个解决方案

#1


把COMMIT放到最后,关闭游标后再COMMIT

#2


需要游标吗?为什么不放datastore或者后台处理。游标,初学者都爱用。最好别用。

#3


是啊,在PB中,要利用数据窗口做所有能做的事情,也就是说,如果一件事,能用数据窗口做,就不要选用其它的方法.这是PB的特点.

另外,用游标很占服务器的资源.如果游标数量过多,会导致服务器资源过多被占用.能不用,就不用.

#4


我曾经给朋友看过他公司的内部收费系统(多前台)非常容易锁表,结果看代码,非常多的游标去填充ddlb,内嵌式sql也非常多。

由于客户端都是通过光纤的远程用户,所以效应慢,用光标更是一个字:死。

可参看:如何作到最小化读取SQL数据库并减轻服务器检索压力的十三点 
http://blog.csdn.net/chengg0769/archive/2007/12/21/1957243.aspx

#5


datastore或者后台处理,我初学,不会用呀,谁能教教我呀?

#6


commit会关闭游标,参照一楼说的,把commit放到close游标之后.
或者使用数据窗口来处理,这样速度比游标要快几十倍

#7


用datawindow也可以,datastore和数据窗口一样,只不过datastore是不可视的.

#8


DECLARE   cs_th_daoru_zz   CURSOR   FOR     
  select   th_ck.fgid,th_ck.quantity 
      from   th_ck   
  where   th_ck.trantype='总装配送' 
        and     th_ck.lastdate> :ldt_maxdatetime; 
open   cs_th_daoru_zz; 
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 
do       while     sqlca.sqlcode=0 
  select       th_zzonland.fgid 
  into   :ll_zzfgid 
  from   th_zzonland   
  where   th_zzonland.fgid=:ll_fgid; 
  if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
          SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
      WHERE   th_zzonland.fgid   =:ll_fgid 
;       
//                commit; //应该放到close之后
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 

loop   
  close   cs_th_daoru_zz; 
commit;

#9


//使用datastore的示例(大意,不合适再调整一下)
string ls_syntax,ls_error
datastore lds_datastore

ls_syntax = sqlca.SyntaxFromSQL("select   th_ck.fgid,th_ck.quantity from   th_ck where   th_ck.trantype='总装配送' and     th_ck.lastdate>"+string(ldt_maxdatetime),"style(type=grid)",ls_error)
if Trim(ls_error) <> "" then
MessageBox("提示信息","生成datastore语法时失败:~r" + ls_error)
return
end if
lds_datastore = Create datastore
if not IsValid(lds_datastore) then return - 1
if lds_datastore.Create(ls_syntax,ls_error) = - 1 then
MessageBox("提示信息","创建datastore时失败:~r" + ls_error)
return
end if
if lds_datastore.SetTransObject(sqlca) = - 1 then return
lds_datastore.Retrieve()

long ll_i,ll_fgid,ll_quantity,ll_zzfgid
for ll_i  = 1 to lds_datastore.rowcount()
ll_fgid=lds_datastore.getitemnumber(ll_i,1)
ll_quantity=lds_datastore.getitemnumber(ll_i,2)
select       th_zzonland.fgid 
into   :ll_zzfgid 
from   th_zzonland   
where   th_zzonland.fgid=:ll_fgid; 
if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
WHERE   th_zzonland.fgid   =:ll_fgid ;       
commit; 
next

#10


DECLARE   cs_th_daoru_zz   CURSOR   FOR     
  select   th_ck.fgid,th_ck.quantity 
      from   th_ck   
  where   th_ck.trantype='总装配送' 
        and     th_ck.lastdate> :ldt_maxdatetime; 
open   cs_th_daoru_zz; 
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 
do       while     sqlca.sqlcode=0 
  select       th_zzonland.fgid 
  into   :ll_zzfgid 
  from   th_zzonland   
  where   th_zzonland.fgid=:ll_fgid; 
  if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
          SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
      WHERE   th_zzonland.fgid   =:ll_fgid 
;       
               
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 

loop   
  close   cs_th_daoru_zz; 
 commit; 

#11


这么多信息怎么不用数据窗口啊?

#1


把COMMIT放到最后,关闭游标后再COMMIT

#2


需要游标吗?为什么不放datastore或者后台处理。游标,初学者都爱用。最好别用。

#3


是啊,在PB中,要利用数据窗口做所有能做的事情,也就是说,如果一件事,能用数据窗口做,就不要选用其它的方法.这是PB的特点.

另外,用游标很占服务器的资源.如果游标数量过多,会导致服务器资源过多被占用.能不用,就不用.

#4


我曾经给朋友看过他公司的内部收费系统(多前台)非常容易锁表,结果看代码,非常多的游标去填充ddlb,内嵌式sql也非常多。

由于客户端都是通过光纤的远程用户,所以效应慢,用光标更是一个字:死。

可参看:如何作到最小化读取SQL数据库并减轻服务器检索压力的十三点 
http://blog.csdn.net/chengg0769/archive/2007/12/21/1957243.aspx

#5


datastore或者后台处理,我初学,不会用呀,谁能教教我呀?

#6


commit会关闭游标,参照一楼说的,把commit放到close游标之后.
或者使用数据窗口来处理,这样速度比游标要快几十倍

#7


用datawindow也可以,datastore和数据窗口一样,只不过datastore是不可视的.

#8


DECLARE   cs_th_daoru_zz   CURSOR   FOR     
  select   th_ck.fgid,th_ck.quantity 
      from   th_ck   
  where   th_ck.trantype='总装配送' 
        and     th_ck.lastdate> :ldt_maxdatetime; 
open   cs_th_daoru_zz; 
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 
do       while     sqlca.sqlcode=0 
  select       th_zzonland.fgid 
  into   :ll_zzfgid 
  from   th_zzonland   
  where   th_zzonland.fgid=:ll_fgid; 
  if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
          SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
      WHERE   th_zzonland.fgid   =:ll_fgid 
;       
//                commit; //应该放到close之后
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 

loop   
  close   cs_th_daoru_zz; 
commit;

#9


//使用datastore的示例(大意,不合适再调整一下)
string ls_syntax,ls_error
datastore lds_datastore

ls_syntax = sqlca.SyntaxFromSQL("select   th_ck.fgid,th_ck.quantity from   th_ck where   th_ck.trantype='总装配送' and     th_ck.lastdate>"+string(ldt_maxdatetime),"style(type=grid)",ls_error)
if Trim(ls_error) <> "" then
MessageBox("提示信息","生成datastore语法时失败:~r" + ls_error)
return
end if
lds_datastore = Create datastore
if not IsValid(lds_datastore) then return - 1
if lds_datastore.Create(ls_syntax,ls_error) = - 1 then
MessageBox("提示信息","创建datastore时失败:~r" + ls_error)
return
end if
if lds_datastore.SetTransObject(sqlca) = - 1 then return
lds_datastore.Retrieve()

long ll_i,ll_fgid,ll_quantity,ll_zzfgid
for ll_i  = 1 to lds_datastore.rowcount()
ll_fgid=lds_datastore.getitemnumber(ll_i,1)
ll_quantity=lds_datastore.getitemnumber(ll_i,2)
select       th_zzonland.fgid 
into   :ll_zzfgid 
from   th_zzonland   
where   th_zzonland.fgid=:ll_fgid; 
if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
WHERE   th_zzonland.fgid   =:ll_fgid ;       
commit; 
next

#10


DECLARE   cs_th_daoru_zz   CURSOR   FOR     
  select   th_ck.fgid,th_ck.quantity 
      from   th_ck   
  where   th_ck.trantype='总装配送' 
        and     th_ck.lastdate> :ldt_maxdatetime; 
open   cs_th_daoru_zz; 
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 
do       while     sqlca.sqlcode=0 
  select       th_zzonland.fgid 
  into   :ll_zzfgid 
  from   th_zzonland   
  where   th_zzonland.fgid=:ll_fgid; 
  if   ll_zzfgid <> 0   then 
UPDATE   th_zzonland     
          SET     th_zzonland.quantity   =:ll_quantity   //10//   th_zzonland.quantity//+99//   quantity+:ll_quantity     
      WHERE   th_zzonland.fgid   =:ll_fgid 
;       
               
fetch   cs_th_daoru_zz   into       :ll_fgid,:ll_quantity; 

loop   
  close   cs_th_daoru_zz; 
 commit; 

#11


这么多信息怎么不用数据窗口啊?