Oracle學習筆記:遊標Cursor

PL/SQL代碼塊中只能用select語句進行賦值 select…into…from….,不能查詢一個結果集
(如需用表請將鼠標移到底部,有創建表代碼)
(1).隱式遊標

begin
     dbms_output.put_line('執行之前,影響的行數:'||SQL%ROWCOUNT);
     delete from orderinfo where orderid=20160002;
     dbms_output.put_line('執行之後,影響的行數:'||SQL%ROWCOUNT);
end;

(2).顯示遊標:定義遊標時指定查詢語句

     CURSOR  遊標名  IS  操作語句;   --1、定義遊標 

     OPEN   遊標名;  --2、打開遊標
     LOOP
       FETCH   遊標名   INTO    變量名;  --3.讀取遊標
             EXIT  WHEN   遊標名%NOTFOUND;
             處理語句;
      END   LOOP;
      CLOSE    遊標名;--4.關閉遊標
    create or replace procedure proc1
    as
      cursor cur_user is select * from userinfo; --1.定義遊標
      theUser userinfo%rowtype; --定義變量與userinfo數據行映射,用於存儲遊標讀取到的數據 
    begin
      --2.打開遊標
      open cur_user;
      LOOP
        --3.獲取遊標的下一行數據
        FETCH CUR_USER INTO theUser;
        --遊標沒有讀到數據退出循環
        exit when CUR_USER%notfound; 
        ---遊標讀到數據就輸出
        dbms_output.put_line(theUser.userId||'  '||theUser.userName);
      END LOOP; 
      dbms_output.put_line('數據備份完畢!');
      --4.關閉遊標
     close cur_user;
     end;

示例2:

create or replace procedure proc1(upoint int)
as
  cursor cur_user is select * from userinfo where userPoint>upoint; --1.定義遊標
  theUser userinfo%rowtype; --定義變量與userinfo數據行映射,用於存儲遊標讀取到的數據 
begin
  --2.打開遊標
  open cur_user;
  LOOP
    --3.獲取遊標的下一行數據
    FETCH CUR_USER INTO theUser;
    --遊標沒有讀到數據退出循環
    exit when CUR_USER%notfound; 
    ---遊標讀到數據就輸出
    dbms_output.put_line(theUser.userId||'  '||theUser.userName);
  END LOOP; 
  dbms_output.put_line('數據備份完畢!');
  --4.關閉遊標
 close cur_user;
end;
call proc1(0);

示例3:帶參數的遊標

create or replace procedure proc1
as
  cursor cur_user(upoint int) is select * from userinfo where userPoint>upoint; --1.定義遊標
  theUser userinfo%rowtype; --定義變量與userinfo數據行映射,用於存儲遊標讀取到的數據 
begin
  --2.打開遊標
  open cur_user(2);
  LOOP
    --3.獲取遊標的下一行數據
    FETCH CUR_USER INTO theUser;
    --遊標沒有讀到數據退出循環
    exit when CUR_USER%notfound; 
    ---遊標讀到數據就輸出
    dbms_output.put_line(theUser.userId||'  '||theUser.userName);
  END LOOP; 
  dbms_output.put_line('數據備份完畢!');
  --4.關閉遊標
 close cur_user;
end;
call proc1();

示例4:for循環讀取遊標

create or replace procedure proc1
as
  cursor cur_user is select * from userinfo; --1.定義遊標
begin

   for theUser in cur_user
   loop
       dbms_output.put_line(theUser.userId||'  '||theUser.userName);
   end loop;
  dbms_output.put_line('數據備份完畢!');
end;

call proc1();

4.引用遊標:定義時不指定查詢語句,打開時指定查詢語句

    TYPE    遊標類型名   IS  REF   CURSOE; --定義類型
    遊標變量名  遊標類型名;  --使用類型定義遊標變量
    OPNE   遊標變量名   FOR   查詢語句;
create or replace procedure proc1(i int)
as
  type refType is ref cursor;--定義類型 ,類型名爲refType
  theCursor refType;--通過類型定義遊標 遊標名爲theCursor
  theUser userInfo%rowtype;
  thePro proInfo%rowtype; 
begin
   if i=1 then
      open theCursor for select * from userInfo;
      loop
          fetch theCursor into theUser;
          exit when theCursor%notfound;
          dbms_output.put_line(theUser.userId||'  '||theUser.userName);
      end loop;
      close theCursor;
   elsif i=2 then
      open theCursor for select * from proInfo;
      loop
          fetch theCursor into thePro;
          exit when theCursor%notfound;
          dbms_output.put_line(thePro.proId||'  '||thePro.proName);
      end loop;
      close theCursor;
   else
     dbms_output.put_line('選擇錯誤!');  
   end if;  
end proc1;
call proc1(2);

創建表空間

create tablespace comDB
datafile 'f:/comDB.dbf'
size 3M;
--會員表
--drop table userInfo
CREATE TABLE USERINFO
(
 USERID INT PRIMARY KEY,
 USERNAME VARCHAR(20) UNIQUE NOT NULL,
 USERPWD VARCHAR(20) NOT NULL,
 USERPOINT INT DEFAULT(0)
);

創建序列

create sequence USERID
start with 1
increment by 1;

添加數據

INSERT INTO USERINFO VALUES(USERID.NEXTVAL,'劉宇','123456',DEFAULT);
INSERT INTO USERINFO VALUES(USERID.NEXTVAL,'spring','123456',DEFAULT);

商品類型表

drop table typeInfo;
create table typeInfo
(
typeId int primary key,
typeName varchar(20) unique not null,
typeDesp varchar(20) not null
)tablespace comDB;

序列

drop sequence typeId;
create sequence typeId
start with 1
increment by 1;

添加數據

insert into typeInfo(typeId,typeName,typeDesp) values(typeId.Nextval,'肉類','香,美味');
insert into typeInfo(typeId,typeName,typeDesp) values(typeId.Nextval,'水果','甜,好吃');

商品信息表

create table proInfo
(
proId int primary key,
proName varchar(20) unique not null,
typeId int references typeInfo(typeId) not null,
proprice float check(proprice>0) not null,
proNum int check(proNum>=0) not null
)tablespace comDB;

序列

--drop sequence proId;
create sequence proId
start with 101
increment by 1;

添加數據

insert into proInfo(proId,proName,typeId,proprice,proNum)  values(proId.Nextval,'牛肉',1,34,45);
insert into proInfo(proId,proName,typeId,proprice,proNum)  values(proId.Nextval,'火龍果',2,17,56);
insert into proInfo(proId,proName,typeId,proprice,proNum)  values(proId.Nextval,'羊肉',1,23,33);
insert into proInfo(proId,proName,typeId,proprice,proNum)  values(proId.Nextval,'梨',2,10,67);

訂單信息表

CREATE TABLE ORDERINFO
(
 ORDERID INT PRIMARY KEY,
 USERID INT REFERENCES USERINFO(USERID),
 PROID INT REFERENCES PROINFO(PROID),
 ORDERNUM INT CHECK(ORDERNUM>0),
 ORDERDATA DATE DEFAULT(SYSDATE)
);

創建序列

create sequence ORDERID
start with 20160001
increment by 1;

訂購商品的存儲過程:
–會員訂購商品的業務:會員編號 商品編號 訂購數量
–涉及的操作:會員積分+2(update) 商品的庫存減少(update) 添加訂單(insert)
–創建存儲過程:
–輸入參數:會員編號 商品編號 訂購數量
–輸出參數:訂單編號

create or replace procedure orderPro(orderUserId int,orderProId int,orderCount int,newOrderId out int)
as
begin
     update userInfo set userPoint=userPoint+2 where userId=orderUserId; --會員積分+2(update)
     update proInfo set proNum=proNum-orderCount where proId=orderProId; --商品的庫存減少
     insert into orderInfo VALUES(ORDERID.Nextval,orderUserId,orderProId,orderCount,default);--添加訂單
     select ORDERID.CURRVAL into newOrderId from dual; --查詢生成的訂單編號並賦值
exception
     when others then
          newOrderId:=-1;
          rollback; --出現異常回滾操作
end orderPro;

測試:調用存儲過程

declare
   newOrderId int;
begin
   orderPro(1,101,50,newOrderId); 
   if newOrderId<0 then
      DBMS_OUTPUT.put_line('訂單失敗!'); 
   else
      DBMS_OUTPUT.put_line('訂購成功,訂單編號爲:'||newOrderId); 
   end if;
end;

查詢數據

SELECT * FROM USERINFO; --用戶
select * from TYPEINFO; --商品類型表
select * from PROINFO; --商品信息表
select * from ORDERINFO; --訂購信息表
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章