1.游標的概念
使用游標(cursor)的一個主要的原因就是把集合操作轉換成單個記錄處理方式。用SQL語言從數據庫中檢索數據後,結果放在內存的一塊區域中,且結果往往是一個含有多個記錄的集合。游標機制允許用戶在SQL server內逐行地訪問這些記錄,按照用戶自己的意願來顯示和處理這些記錄。
2.游標的用法
一般地,使用游標都遵循下列的常規步驟:
(1) 聲明游標。把游標與T-SQL語句的結果集聯系起來。
(2) 打開游標。
(3) 使用游標操作數據。
(4) 關閉游標。
3.經典案例
I要求:
利用游標轉換兩張表的數據。
首先,將滿足以下三個條件的數據插入到一張新表(productinfo_tmp)中 :
<1>價格大於1000
<2>產地為“中國”或“杭州”
<3> 商品類型為“家電”或“電子產品”
然後,在新表(productinfo_tmp)中進行如下兩個操作:
<1>價格大於2000的下調5%
<2>商品類型編號轉換為商品類型名稱
II 分析:
在獲得包含數據的商品信息表和商品類型信息表兩張表之後,在PL/SQL語句塊中進行如下5步操作:
<1>創建新表(productinfo_tmp);
<2>利用SQL語句把符合要求的數據查詢出來;
<3>把符合要求的數據插入新表(productinfo_tmp);
<4>在新表(productinfo_tmp)中把價格大於2000的下調5%
<5>在新表(productinfo_tmp)中把商品類型編號轉換為商品類型名稱
|||建原始表並插入數據
--創建原始表
create table categoryinfo
(
cid varchar2(10) primary key,
cname varchar2(20)
);
commit;
create table productinfo
(
pid varchar2(10) primary key,
pname varchar2(20),
price number(8,2),
quanty number(10),
category varchar2(10),
desperation varchar2(1000),
origin varchar2(20)
);
commit;
--插入原始數據
insert into categoryinfo(cid,cname) values('01','食品');
insert into categoryinfo(cid,cname) values('02','家電');
insert into categoryinfo(cid,cname) values('03','洗化');
insert into categoryinfo(cid,cname) values('04','電子產品');
insert into categoryinfo(cid,cname) values('05','辦公用品');
insert into categoryinfo(cid,cname) values('06','玩具');
insert into categoryinfo(cid,cname) values('07','文具');
commit;
insert into productinfo(pid,pname,price,quanty,category,desperation,origin) values('001','紙巾',20,10000,'03','原生木漿','河北');
insert into productinfo(pid,pname,price,quanty,category,desperation,origin) values('002','筆記本電腦',5000,300,'04','堅如磐石,中國品質','中國');
insert into productinfo(pid,pname,price,quanty,category,desperation,origin) values('003','冰箱',7000,900,'02','每晚只用一度電','杭州');
insert into productinfo(pid,pname,price,quanty,category,desperation,origin) values('004','U盤',50,500,'04','隨插隨拔','中國');
insert into productinfo(pid,pname,price,quanty,category,desperation,origin) values('005','空調',4000,100,'02','讓你四季如春','杭州');
commit;
--創建一個字段屬性與productinfo表相同的空表
create table productinfo_tmp as select * from productinfo where 1=0;||||在PL/SQL語句塊中實現任務要求
declare
--定義變量,分別存放商品類別的編號和名稱
v_cid categoryinfo.cid%type;
v_cname categoryinfo.cname%type;
--定義變量,存放商品信息的記錄
v_prod productinfo%rowtype;
--定義臨時變量
tmpnum number(8,0);
--定義游標
cursor cur_prdt_catg is
select * from productinfo where price>1000 and origin in('中國','杭州')
and category in
(select cid from categoryinfo where cname in('電子產品','家電')
);
cursor cur_catg is
select cid,cname from categoryinfo
where cname in ('電子產品','家電');
begin
--把符合要求是數據放進新表
open cur_prdt_catg; --打開游標
Loop
fetch cur_prdt_catg into v_prod;
if cur_prdt_catg%found then
insert into productinfo_tmp (pid,pname,price,quanty,category,desperation,origin)
values(v_prod.pid,v_prod.pname,v_prod.price,v_prod.quanty,v_prod.category,v_prod.desperation,v_prod.origin);
else
dbms_output.put_line('已取出所有符合條件的數據,共'||cur_prdt_catg%rowcount||'條');
exit;
end if;
end loop;
commit;
--轉換產品類型
open cur_catg;
tmpnum:=0;
loop
fetch cur_catg into v_cid,v_cname;
if cur_catg%found then
update productinfo_tmp set productinfo_tmp.category=v_cname
where category=v_cid;
if sql%found then
tmpnum:=tmpnum+sql%rowcount;
end if;
else
dbms_output.put_line('產品類型轉換完畢,共轉換'||tmpnum||'條');
exit;
end if;
end loop;
--產品價格下調
update productinfo_tmp set productinfo_tmp.price=productinfo_tmp.price*0.95
where productinfo_tmp.price>2000;
dbms_output.put_line('產品價格更改完畢,共更改'||sql%rowcount||'條');
commit;
end;

代碼圖:
