Oracle數據庫—— 游標的創建和應用


一、涉及內容

  游標的創建與應用

二、具體操作

 (一)填空題

  1.PL/SQL 程序塊主要包含3個部分:聲明部分、(執行部分 )、異常處理部分。

  2.自定義異常必須使用(RAISE )語句引發。

(二)選擇題

  1.下列哪一個不是BOOLEAN變量可能的取值?(D )

    A.TRUE  B.FALSE  C.NULL D.BLANK

  2.請查看以下IF語句:

Declare
     sal number:=500;
     comm number;
  Begin 
     If sal <100 then 
        Comm :=0;
     Elsif sal <600 then
        Comm: =sal*0.1;
     Else sal <1000 then
        Comm: =sal*0.15;
     Else 
        Comm: =sal*0.2;
     End if;
  End;

  在執行了以上語句之后,變量comm 的結果應是:(B )

  A.0  B.50  C.75 D.100

  3.在以下哪些語句中可以包含WHERE CURRENT OF 子句?(CE)

    A.OPEN   B.FETCH C.DELETE D.SELECT E.UPDATE   F.CURSOR

  4.在異常和oracle錯誤之間建立關聯時,應該在哪個部分完成?(A)

    A.定義部分   B.執行部分  C.異常處理部分

  5.只能存在一個值的變量是哪種變量?(B )

    A.游標   B.標量變量  C.游標變量 D.記錄變量

 

(三)編程題

  1.編寫程序計算並輸出1~100的和。

  方案一:    

  語句:

Declare 
   v_sum  integer:=0;
begin 
   for i in 1..100 loop
      v_sum := v_sum+i;
   end loop;
   dbms_output.put_line(‘1~100的和為:’|| v_sum);
end;
/

  截圖:

                      

  方案二:

  語句:

Declare 
   v_sum  integer;
begin 
    v_sum := 100*101/2;
    dbms_output.put_line(‘1~100的和為:’|| v_sum);
end;
/

  截圖:

 

  2.分別使用顯式游標和隱式游標逐行輸出scott.emp表中的員工姓名和工資。

  (一)使用顯式游標

   語句:

DECLARE
   CURSOR emp_cursor01 IS SELECT ename,sal FROM scott.emp;
   emp_record emp_cursor01%ROWTYPE; 
BEGIN
   OPEN emp_cursor01 ;
   LOOP
      FETCH emp_cursor01 INTO emp_record;
      EXIT WHEN emp_cursor01%NOTFOUND;
     dbms_output.put_line('ename:'||emp_record.ename||',sal:'||emp_record.sal);
   END LOOP;
   dbms_output.put_line('row count:'||emp_cursor01%rowcount);
    CLOSE emp_cursor01;
END;

   截圖:

 

  (二)使用隱式游標

  語句:

BEGIN
   FOR emp_record IN (SELECT ename,sal  FROM scott.emp) 
   LOOP
     dbms_output.put_line('ename:'||emp_record.ename||',sal:'||emp_record.sal);
   END LOOP;
END; 

  截圖:

 

 

(補充練習)

1、 創建一個表top_dogs,包含兩列:name varchar2(25) 和 salary NUMBER(11,2),用來存放員工姓名和工資。

語句:

create table top_dogs
 (name varchar2(25),
  salary NUMBER(11,2));

截圖:

 

2、創建一個PL/SQL塊,查詢出工資水平前n名的員工。具體要求如下:

(1)通過替代變量讀取n的值。

(2)通過循環從emp表中獲取工資在前n名的員工的姓名和工資

(3)將得到的員工姓名和工資寫入top_dogs表。

(4)如果有多名員工的工資相同,則每人都占n名中的一個名額。

(5)測試特殊情況,例如n=0或者n大於員工總數。

(6)每次向top_dogs 表中寫入數據前,先清空該表中的數據。

方案一:

語句:

DECLARE
   CURSOR emp_cursor(n number) IS SELECT ename,sal FROM scott.emp 
   ORDER BY sal DESC;
   v_n integer := &n;
BEGIN
   delete from top_dogs;
   FOR rec IN emp_cursor(v_n)  LOOP
      IF emp_cursor%ROWCOUNT <=v_n THEN
         insert into top_dogs  values(rec.ename,rec.sal);      
         dbms_output.put_line('ename: '||rec.ename||'  sal:'||rec.sal);
      ELSIF v_n<=0 or v_n>emp_cursor%ROWCOUNT  then 
         dbms_output.put_line('error!');
      ELSE EXIT;    --退出循環
      END IF;
   END LOOP;
END;
/

截圖:

 

n=3以及n=4:

 

測試n=0以及n=100的情況:

        

方案二:

語句:

DECLARE
   CURSOR emp_cursor IS SELECT ename,sal FROM scott.emp 
   ORDER BY sal DESC;
   v_n integer := &n;
BEGIN
   delete from top_dogs;
   FOR rec IN emp_cursor  
LOOP
        Exit when emp_cursor%notfound;
        Exit when emp_cursor%ROWCOUNT>v_n;
        insert into top_dogs values(rec.ename,rec.sal);      
        -- dbms_output.put_line('ename: '||rec.ename||'  sal:'||rec.sal);
      END LOOP;
END;
/

截圖:

 輸入n:2

輸入n:3

Select * from top_dogs

 

輸入n:0

Select * from top_dogs

 

輸入n:100

Select * from top_dogs

 

 

3、在上題的基礎上,如果員工工資相同(並列第幾名),需要將前n名的員工全部輸出。

語句:

DECLARE
   CURSOR emp_cursor IS SELECT ename,sal FROM scott.emp 
   ORDER BY sal DESC;
   v_n integer := &n;
   v_sal scott.emp.sal%type;
BEGIN
   delete from top_dogs;
   FOR rec IN emp_cursor  
LOOP
        Exit when emp_cursor%notfound;
        Exit when emp_cursor%ROWCOUNT>v_n and v_sal<>rec.sal;
        V_sal:= rec.sal;
        insert into top_dogs values(rec.ename,rec.sal);      
        -- dbms_output.put_line('ename: '||rec.ename||'  sal:'||rec.sal);
      END LOOP;
END;

輸入n 的值:2

Select * from top_dogs

有三條記錄

截圖:

 

4、使用游標查詢dept表的部門編號和名稱,將其部門編號傳遞給另一個用於查詢emp表的游標(查詢emp表的員工姓名,工作,雇佣日期,工資)。

語句:

Declare
   Cursor dept_cur is select deptno,dname from scott.dept;
   Cursor emp_cur (c_deptno scott.emp.deptno%type) is select ename,job,hiredate,sal from scott.emp where deptno=c_deptno;
   Emp_rec emp_cur%rowtype;
Begin
   For dept_rec in dept_cur
   Loop
     Open emp_cur(dept_rec.deptno);
     Loop
       Fetch emp_cur into Emp_rec;
       Exit when emp_cur%notfound;
       Dbms_output.put_line('ename:'|| Emp_rec.ename||' job:'|| Emp_rec.job||' hiredate:'|| Emp_rec.hiredate||' sal:'|| Emp_rec.sal);
     End loop;
     Close emp_cur;
   End loop;
End;
/

截圖:

 

5、為emp表增加一個列stars,類型為VARCHAR2(100)。使用游標更新stars列:創建一個PL/SQL塊,根據員工的工資計算他能獲得的星號“*”數量,每100美元獎勵一個星號,按四舍五入處理。並根據員工所獲得的星號數量n,形成由n個星號組成的字符串,寫入emp表的stars列。

(1)為emp表增加一個列stars,類型為VARCHAR2(100)。

 

(2)使用游標更新stars列:

語句:

Declare
    v_stars scott.emp.stars%type;
    v_num number:=0;
    Cursor c1 is select empno,sal,stars from scott.emp;
 Begin
    For emp_rec in c1
    Loop
      v_stars:='';
      exit when c1%notfound;
      v_num:=round(emp_rec.sal/100);
    for i in 1..v_num
    loop
      v_stars:= v_stars||'*';
    end loop;
    update scott.emp set stars= v_stars where empno=emp_rec.empno;
    end loop;
    end;

截圖:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM