oracle中利用游标更新表中的记录集...
时间:2010-08-12 来源:hnxx1986
前几天,一个朋友找我帮忙,叫我帮他写一个oralce语句,需求如下:他有一张表,里面a,b,money字段,a字段有些值是相等的,b有很多记录,其中有些记录是2,3,他想将a值相同的记录,b=2的money更新为b=3的记录的money加上b=2的money总和,而将b=3的记录里面的money的值更新为0,我考虑了一下,
第一步:
首先要将 a1=a2 并且b=3的记录查出来,而这个记录集是包含多条记录
第二步:
既然是个记录集,就不能简单的“=”了事,要遍历才行,但是遍历的话一般用游标是个不错的选择
第三步:
编写sql
见表语句如下:
create table TEST1
(
TID VARCHAR2(20),//主键
TNAME VARCHAR2(20),//名称
TMONEY NUMBER,//金额
TCODE NUMBER,//编号
TPRO_CODE VARCHAR2(20)//厂家代码
);
//以下是利用游标来遍历重复的记录行数,并更新表中金额的数据(以下语句纯属个人学习所用,有不当的地方,还请各位指教)
declare
v_cur test1%rowType;//声明游标的类型为表类型
cursor p_ret is select distinct a.tid,a.tname,a.tmoney,a.tcode,a.tpro_code
from test1 a join test1 b on a.tpro_code = b.tpro_code and a.tcode = 3;//利用内连接查询(用这种方法只能用内连接,用外连接是不对的),并用distinct来去掉重复的行数
begin
open p_ret ;//打开游标,显示的游标需要手动的打开关闭
loop //循环开始
fetch p_ret into v_cur; //将值赋到v_cur中
//==========当游标退出之前还会到这里执行一次,因此更新的语句不能写在此处,比如你游标明明只有两条记录,但是它会在这里执行三次的
exit when p_ret%NOTFOUND;//游标中没有值的时候退出
dbms_output.put_line('tid :'||v_cur.tid||' tname :'||v_cur.tname||' tmoney :'||v_cur.tmoney||' tcode :'||v_cur.tcode); //打印测试值
update test1 a set a.tmoney = v_cur.tmoney + a.tmoney where a.tpro_code = v_cur.tpro_code and a.tcode = 2; //将tcode =2 的金额更新为 2和3的总金额
update test1 b set b.tmoney = 0 where b.tpro_code = v_cur.tpro_code and b.tcode = 3;//将tcode的金额更新为0
end loop;
commit;
close p_ret ;
end;
第二种:
declare
v_cur test1%rowType;
cursor p_ret is select a.tid,a.tname,a.tmoney,a.tcode,a.tpro_code from test1 a join (
select c.tpro_code,count(*) cnt from test1 c group by c.tpro_code having count(*)>1
) b on a.tpro_code = b.tpro_code and a.tcode = 3;//第二种方法与第一种大致相同,只是在找出重复行的时候的的方法不通而已,先用group by对厂商编号进行分组然后再查出条件为3的记录集
begin
open p_ret ;
loop
fetch p_ret into v_cur;
exit when p_ret%NOTFOUND;
dbms_output.put_line('tid :'||v_cur.tid||' tname :'||v_cur.tname||' tmoney :'||v_cur.tmoney||' tcode :'||v_cur.tcode);
update test1 a set a.tmoney = v_cur.tmoney + a.tmoney where a.tpro_code = v_cur.tpro_code and a.tcode = 2;
update test1 b set b.tmoney = 0 where b.tpro_code = v_cur.tpro_code and b.tcode = 3;
end loop;
commit;
close p_ret ;
end;