PB 游标更新数据出错,请各位帮忙

时间:2022-02-18 19:54:21
SQL> desc ng_store_sales
 名称                             空?      类型
 -------------------------------- -------- -----------------------
 BUYER_UID                                 VARCHAR2(6)
 STORE_NO                                  NUMBER(5)
 SALE_AMOUNT                               NUMBER
 SALE_AMOUNT_BUYER                         NUMBER
 MONTH                                     NUMBER(2)
 YEAR                                      NUMBER(4)

游标如下:
real tsales;
string tbuyer;


declare buy cursor for
 select buyer_uid,sum(sale_amount)
 from ng_store_sales
 where year= :lsyear and month= :lsmonth 
 group by buyer_uid
 ;
 
 open buy ;
 do while sqlca.sqlcode=0;
fetch buy into :tbuyer,:tsales;
 update ng_store_sales set SALE_AMOUNT_BUYER= :tsales
 where buyer_uid=:tbuyer and year= :lsyear and month= :lsmonth ;
   fetch buy into :tbuyer,:tsales;
 loop;
close buy;

commit;

按buyer_uid汇总ng_store_sales表里sale_amount字段数据,更新sale_amount_buyer字段

SQL>  select buyer_uid,sum(sale_amount)
  2   from ng_store_sales group by buyer_uid;

BUYER_ SUM(SALE_AMOUNT)
------ ----------------
F1           1570627.17
F2           3445516.92
F3            763568.04
F4             715882.3
F5           5093196.31

执行游标后的,结果如下面:

select distinct buyer_uid,sale_amount_buyer from ng_store_sales;

BUYER_ SALE_AMOUNT_BUYER
------ -----------------
F1            1570627.13
F2               3445517
F3                     0
F4            715882.313
F5                     0


为何数据只更新一半?

8 个解决方案

#1


 year= :lsyear and month= :lsmonth 
更新时还有year和month条件,最后查询时,又没有这两个条件,结果当然可能不同

#2


1、建议:你这个完全无需游标来实现,游标实现这样的功能非常慢,你可以直接使用一句更新语句进行更新
2、问题:你这个cursor执行过程完全可能出现sql问题,open cursor时,sqlcode为0,但是你fetch时可恩呢个sqlcode就不是0。当然你更新语句可能也不成功!
open buy ;
do while sqlca.sqlcode=0;
  fetch buy into :tbuyer,:tsales;
  if sqlca.sqlcode <> 0 then
     rollback using sqlca;
     messageBox("提示","失败",stopSign!)
     return
  end if
  update ng_store_sales set SALE_AMOUNT_BUYER= :tsales
  where buyer_uid=:tbuyer and year= :lsyear and month= :lsmonth ;
  if sqlca.sqlcode <> 0 then
     rollback using sqlca;
     messageBox("提示","失败",stopSign!)
     return
  end if
  fetch buy into :tbuyer,:tsales;
loop;
close buy;

#3


引用 2 楼 new4everlau 的回复:
1、建议:你这个完全无需游标来实现,游标实现这样的功能非常慢,你可以直接使用一句更新语句进行更新
2、问题:你这个cursor执行过程完全可能出现sql问题,open cursor时,sqlcode为0,但是你fetch时可恩呢个sqlcode就不是0。当然你更新语句可能也不成功!
open buy ;
do while sqlca.sqlcode=0;
  fetch buy into ……


对于您的第一个建议是可以,
对于您的第二个,好象不对

#4


引用 1 楼 xys_777 的回复:
year= :lsyear and month= :lsmonth 
更新时还有year和month条件,最后查询时,又没有这两个条件,结果当然可能不同

查询是没加这两个条件,是因为表里就一个月的数据,所以查询没加,跟这个无关的,不过,还是谢谢你

#5


客气!
1、你select也加了,update也加了,都是同一个条件,一条语句更新绝对没问题
2、对于第二个,至于为什么要加判断,琢磨下吧

#6


引用 5 楼 new4everlau 的回复:
客气!
1、你select也加了,update也加了,都是同一个条件,一条语句更新绝对没问题
2、对于第二个,至于为什么要加判断,琢磨下吧


如果是复杂的计算更新,一条语句更新可能不行吧,要么就用触发器?

对于第二个,本来还能执行,加上你那个判断,根本执行不了, 忘了说了,数据库是oracle 8i

#7


针对你这个问题,不是针对所有的问题;
如果加个判断不能执行说明语句有问题,如果没问题至少也说明ORACLE和MSSQL不同

#8


找到原因了,谢谢各位的热情
有两句的位子颠倒了
do while ...
 fetch ...

#1


 year= :lsyear and month= :lsmonth 
更新时还有year和month条件,最后查询时,又没有这两个条件,结果当然可能不同

#2


1、建议:你这个完全无需游标来实现,游标实现这样的功能非常慢,你可以直接使用一句更新语句进行更新
2、问题:你这个cursor执行过程完全可能出现sql问题,open cursor时,sqlcode为0,但是你fetch时可恩呢个sqlcode就不是0。当然你更新语句可能也不成功!
open buy ;
do while sqlca.sqlcode=0;
  fetch buy into :tbuyer,:tsales;
  if sqlca.sqlcode <> 0 then
     rollback using sqlca;
     messageBox("提示","失败",stopSign!)
     return
  end if
  update ng_store_sales set SALE_AMOUNT_BUYER= :tsales
  where buyer_uid=:tbuyer and year= :lsyear and month= :lsmonth ;
  if sqlca.sqlcode <> 0 then
     rollback using sqlca;
     messageBox("提示","失败",stopSign!)
     return
  end if
  fetch buy into :tbuyer,:tsales;
loop;
close buy;

#3


引用 2 楼 new4everlau 的回复:
1、建议:你这个完全无需游标来实现,游标实现这样的功能非常慢,你可以直接使用一句更新语句进行更新
2、问题:你这个cursor执行过程完全可能出现sql问题,open cursor时,sqlcode为0,但是你fetch时可恩呢个sqlcode就不是0。当然你更新语句可能也不成功!
open buy ;
do while sqlca.sqlcode=0;
  fetch buy into ……


对于您的第一个建议是可以,
对于您的第二个,好象不对

#4


引用 1 楼 xys_777 的回复:
year= :lsyear and month= :lsmonth 
更新时还有year和month条件,最后查询时,又没有这两个条件,结果当然可能不同

查询是没加这两个条件,是因为表里就一个月的数据,所以查询没加,跟这个无关的,不过,还是谢谢你

#5


客气!
1、你select也加了,update也加了,都是同一个条件,一条语句更新绝对没问题
2、对于第二个,至于为什么要加判断,琢磨下吧

#6


引用 5 楼 new4everlau 的回复:
客气!
1、你select也加了,update也加了,都是同一个条件,一条语句更新绝对没问题
2、对于第二个,至于为什么要加判断,琢磨下吧


如果是复杂的计算更新,一条语句更新可能不行吧,要么就用触发器?

对于第二个,本来还能执行,加上你那个判断,根本执行不了, 忘了说了,数据库是oracle 8i

#7


针对你这个问题,不是针对所有的问题;
如果加个判断不能执行说明语句有问题,如果没问题至少也说明ORACLE和MSSQL不同

#8


找到原因了,谢谢各位的热情
有两句的位子颠倒了
do while ...
 fetch ...