Oracle PLSQL游標、游標變數的使用

来源:https://www.cnblogs.com/yongestcat/archive/2019/08/12/11340071.html
-Advertisement-
Play Games

參考文章:https://www.cnblogs.com/huyong/archive/2011/05/04/2036377.html在 PL/SQL 程式中,對於處理多行記錄的事務經常使用游標來實現使用有四個步驟:定義、打開、提取、關閉例子:09:52:04 SCOTT@std1> DECLARE... ...


參考文章:https://www.cnblogs.com/huyong/archive/2011/05/04/2036377.html

在 PL/SQL 程式中,對於處理多行記錄的事務經常使用游標來實現

使用有四個步驟:定義、打開、提取、關閉

例子:

09:52:04 SCOTT@std1> DECLARE
09:52:07   2     CURSOR c_cursor 
09:52:07   3     IS SELECT ename, sal 
09:52:07   4     FROM emp 
09:52:07   5     WHERE rownum<11;   
09:52:07   6     v_ename  emp.ename%TYPE;
09:52:07   7     v_sal    emp.ename%TYPE;   
09:52:07   8  BEGIN
09:52:07   9    OPEN c_cursor;
09:52:07  10    FETCH c_cursor INTO v_ename, v_sal;
09:52:07  11    WHILE c_cursor%FOUND LOOP
09:52:07  12       DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) );
09:52:07  13       FETCH c_cursor INTO v_ename, v_sal;
09:52:07  14    END LOOP;
09:52:07  15    CLOSE c_cursor;
09:52:08  16  END;
09:52:09  17  /
SMITH---800
ALLEN---1600
WARD---1250
JONES---2975
MARTIN---1250
BLAKE---2850
CLARK---2450
SCOTT---3000
TURNER---1500
ADAMS---1100
 
PL/SQL procedure successfully completed.
 
Elapsed: 00:00:00.00
10:01:43 SCOTT@std1> DECLARE
11:31:04   2    deptrec dept%Rowtype;
11:31:04   3    dept_name dept.dname%TYPE;
11:31:04   4    dept_loc dept.loc%TYPE;
11:31:04   5    CURSOR c1 IS SELECT dname,loc FROM dept WHERE deptno<=30;
11:31:04   6    CURSOR c2(dept_no NUMBER DEFAULT 10) IS SELECT dname,loc FROM dept WHERE deptno <= dept_no;
11:31:04   7    CURSOR c3(dept_no NUMBER DEFAULT 10) IS SELECT * FROM dept WHERE deptno <= dept_no;
11:31:04   8    
11:31:04   9  BEGIN
11:31:04  10   OPEN c1;
11:31:04  11   LOOP 
11:31:04  12     FETCH c1 INTO dept_name,dept_loc;
11:31:04  13     EXIT WHEN c1%NOTFOUND;
11:31:04  14     dbms_output.put_line(dept_name||'---'||dept_loc);
11:31:04  15   END LOOP;
11:31:04  16   CLOSE c1;
11:31:04  17   
11:31:04  18   OPEN c2;
11:31:04  19   LOOP
11:31:04  20     FETCH c2 INTO dept_name,dept_loc;
11:31:04  21     EXIT WHEN c2%NOTFOUND;
11:31:04  22     dbms_output.put_line(dept_name||'---'||dept_loc);
11:31:04  23   END LOOP;
11:31:04  24   CLOSE c2;
11:31:04  25   
11:31:04  26   OPEN c3(dept_no => 20);
11:31:04  27   LOOP
11:31:04  28     FETCH c3 INTO deptrec;
11:31:04  29     EXIT WHEN c3%NOTFOUND;
11:31:04  30     dbms_output.put_line(deptrec.deptno||'---'||deptrec.dname||'---'||deptrec.loc);
11:31:04  31   END LOOP;
11:31:04  32   CLOSE c3;
11:31:04  33  END;
11:31:06  34  /
ACCOUNTING---NEW YORK
RESEARCH---DALLAS
SALES---CHICAGO
ACCOUNTING---NEW YORK
10---ACCOUNTING---NEW YORK
20---RESEARCH---DALLAS

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.02
11:31:07 SCOTT@std1> 

游標屬性: Cursor_name%FOUND 布爾型屬性,當最近一次提取游標操作FETCH成功則為 TRUE,否則為FALSE; Cursor_name%NOTFOUND 布爾型屬性,與%FOUND相反; Cursor_name%ISOPEN 布爾型屬性,當游標已打開時返回 TRUE; Cursor_name%ROWCOUNT 數字型屬性,返回已從游標中讀取的記錄數 例子

15:04:04 SCOTT@std1> set serverout on
15:04:27 SCOTT@std1> DECLARE
15:04:40   2    v_empno emp.empno%TYPE;
15:04:40   3    v_sal emp.sal%TYPE;
15:04:40   4    CURSOR c_cursor IS SELECT empno,sal FROM emp;  
15:04:40   5  BEGIN
15:04:40   6    OPEN c_cursor;
15:04:40   7    LOOP
15:04:40   8      FETCH c_cursor INTO v_empno,v_sal;
15:04:40   9      EXIT WHEN c_cursor%NOTFOUND;
15:04:40  10      IF v_sal<1200 THEN 
15:04:40  11        UPDATE emp SET sal=sal+50 WHERE empno=v_empno;
15:04:41  12        dbms_output.put_line('編碼為'||v_empno||'工資已更新!');
15:04:41  13      END IF;
15:04:41  14    END LOOP;
15:04:41  15    CLOSE c_cursor;
15:04:41  16  END;
15:04:42  17  /
編碼為7369工資已更新!
編碼為7876工資已更新!
編碼為7900工資已更新!

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
15:04:43 SCOTT@std1> 
15:04:43 SCOTT@std1> DECLARE
15:06:12   2    v_name emp.ename%TYPE;
15:06:12   3    v_job emp.job%TYPE;
15:06:12   4    CURSOR c1 IS SELECT ename,job FROM emp WHERE deptno=20;
15:06:12   5  BEGIN
15:06:12   6    OPEN c1;
15:06:12   7    LOOP 
15:06:12   8      FETCH c1 INTO v_name,v_job;
15:06:12   9      IF c1%FOUND THEN 
15:06:12  10        dbms_output.put_line(v_name||'的崗位是'||v_job);
15:06:12  11      ELSE 
15:06:12  12        dbms_output.put_line('已經處理完結果');
15:06:12  13        EXIT;
15:06:12  14      END IF;
15:06:12  15    END LOOP;
15:06:12  16    CLOSE c1;
15:06:12  17  END;
15:06:14  18  /
SMITH的崗位是CLERK
JONES的崗位是MANAGER
SCOTT的崗位是ANALYST
ADAMS的崗位是CLERK
FORD的崗位是ANALYST
已經處理完結果

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
15:06:15 SCOTT@std1> 
15:06:15 SCOTT@std1> DECLARE
15:38:26   2    v_ename emp.ename%TYPE;
15:38:26   3    v_hiredate emp.hiredate%TYPE;
15:38:26   4    CURSOR c1(dept_id NUMBER,jobid VARCHAR2) IS SELECT ename,hiredate FROM emp WHERE deptno=dept_id AND job=jobid;
15:38:26   5  BEGIN
15:38:26   6    OPEN c1(30,'SALESMAN');
15:38:26   7    LOOP
15:38:26   8      FETCH c1 INTO v_ename,v_hiredate;
15:38:26   9      IF c1%FOUND THEN 
15:38:26  10        dbms_output.put_line(v_ename||'的雇佣日期是:'||v_hiredate);
15:38:26  11      ELSE
15:38:26  12        dbms_output.put_line('結果集處理完了');
15:38:26  13        EXIT;
15:38:26  14      END IF;    
15:38:26  15    END LOOP;
15:38:26  16    CLOSE c1;
15:38:26  17  END;
15:38:27  18  /
ALLEN的雇佣日期是:20-FEB-81
WARD的雇佣日期是:22-FEB-81
MARTIN的雇佣日期是:28-SEP-81
TURNER的雇佣日期是:08-SEP-81
結果集處理完了

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
15:38:28 SCOTT@std1> 
15:38:28 SCOTT@std1> DECLARE
16:22:36   2    TYPE emp_record_type IS RECORD(
16:22:36   3      v_ename emp.ename%TYPE,
16:22:36   4      v_hiredate emp.hiredate%TYPE);
16:22:36   5    v_emp_record emp_record_type;
16:22:36   6    
16:22:36   7    CURSOR c1(dept_id NUMBER,jobid VARCHAR2) RETURN emp_record_type IS SELECT ename,hiredate FROM emp WHERE deptno=dept_id AND job=jobid;
16:22:36   8  BEGIN
16:22:36   9    OPEN c1(20,'CLERK');
16:22:36  10    LOOP
16:22:36  11      FETCH c1 INTO v_emp_record;
16:22:36  12      IF c1%FOUND THEN 
16:22:36  13        dbms_output.put_line(v_emp_record.v_ename||'的雇佣日期是:'||v_emp_record.v_hiredate);
16:22:36  14      ELSE
16:22:36  15        dbms_output.put_line('結果集處理完了');
16:22:36  16        EXIT;
16:22:36  17      END IF;    
16:22:36  18    END LOOP;
16:22:36  19    CLOSE c1;
16:22:36  20  END;
16:22:37  21  /
SMITH的雇佣日期是:17-DEC-80
ADAMS的雇佣日期是:23-MAY-87
結果集處理完了

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
16:22:38 SCOTT@std1> 
16:22:38 SCOTT@std1> DECLARE  
16:31:29   2    CURSOR c1(dept_id NUMBER,jobid VARCHAR2)  IS SELECT ename,hiredate FROM emp WHERE deptno=dept_id AND job=jobid;
16:31:29   3     v_emp_record c1%ROWTYPE;
16:31:29   4  BEGIN
16:31:29   5    OPEN c1(20,'CLERK');
16:31:29   6    LOOP
16:31:29   7      FETCH c1 INTO v_emp_record;
16:31:29   8      IF c1%FOUND THEN 
16:31:29   9        dbms_output.put_line(v_emp_record.ename||'的雇佣日期是:'||v_emp_record.hiredate);
16:31:29  10      ELSE
16:31:29  11        dbms_output.put_line('結果集處理完了');
16:31:29  12        EXIT;
16:31:29  13      END IF;    
16:31:29  14    END LOOP;
16:31:29  15    CLOSE c1;
16:31:29  16  END;
16:31:30  17  /
SMITH的雇佣日期是:17-DEC-80
ADAMS的雇佣日期是:23-MAY-87
結果集處理完了

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
16:31:31 SCOTT@std1> 

游標的FOR迴圈 能自動執行游標的open、fetch、close和迴圈 例子:

16:31:31 SCOTT@std1> DECLARE
16:43:57   2    CURSOR c1 IS SELECT deptno,ename,sal FROM emp;
16:43:57   3  BEGIN
16:43:57   4    FOR v1 IN c1 LOOP
16:43:57   5      dbms_output.put_line(v1.deptno||'---'||v1.ename||'---'||v1.sal);
16:43:57   6    END LOOP;
16:43:57   7  END;
16:43:58   8  /
20---SMITH---850
30---ALLEN---1600
30---WARD---1250
20---JONES---2975
30---MARTIN---1250
30---BLAKE---2850
10---CLARK---2450
20---SCOTT---3000
30---TURNER---1500
20---ADAMS---1150
30---JAMES---1000
20---FORD---3000
10---MILLER---1300

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
16:43:59 SCOTT@std1> 
16:43:59 SCOTT@std1> DECLARE
16:58:03   2    CURSOR c1(dept_no NUMBER DEFAULT 10) IS SELECT deptno,dname,loc FROM dept WHERE deptno=dept_no;
16:58:03   3  BEGIN
16:58:03   4    dbms_output.put_line('當dept_no參數值為30:');
16:58:03   5    FOR v1 IN c1(30) LOOP   dbms_output.put_line(v1.deptno||'---'||v1.dname||'---'||v1.loc);
16:58:03   6    END LOOP;
16:58:03   7    dbms_output.put_line('當dept_no參數值為10:');
16:58:03   8    FOR v1 IN c1 LOOP   dbms_output.put_line(v1.deptno||'---'||v1.dname||'---'||v1.loc);
16:58:04   9    END LOOP;
16:58:04  10  END;
16:58:04  11  /
當dept_no參數值為30:
30---SALES---CHICAGO
當dept_no參數值為10:
10---ACCOUNTING---NEW YORK

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
16:58:05 SCOTT@std1> 

PL/SQL還允許在游標FOR迴圈語句中使用子查詢來實現游標的功能 例子

16:58:05 SCOTT@std1> BEGIN
17:03:37   2    FOR v1 IN (SELECT dname,loc FROM dept) LOOP
17:03:37   3    dbms_output.put_line(v1.dname||'---'||v1.loc); 
17:03:37   4    END LOOP;
17:03:37   5  END;
17:03:38   6  /
ACCOUNTING---NEW YORK
RESEARCH---DALLAS
SALES---CHICAGO
OPERATIONS---BOSTON

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
17:03:38 SCOTT@std1>

隱式游標

image例: 刪除EMPLOYEES表中某部門的所有員工,如果該部門中已沒有員工,則在DEPARTMENT表中刪除該部門

17:36:32 SCOTT@std1> DECLARE 
17:36:53   2    v_deptno emp.deptno%TYPE:=&p_deptno;
17:36:53   3  BEGIN
17:36:53   4    DELETE FROM emp WHERE deptno=v_deptno;
17:36:53   5    IF SQL%NOTFOUND THEN 
17:36:53   6      DELETE FROM dept WHERE deptno=v_deptno;
17:36:53   7    END IF;
17:36:53   8  END;
17:36:54   9  /
Enter value for p_deptno: 10
old   2:   v_deptno emp.deptno%TYPE:=&p_deptno;
new   2:   v_deptno emp.deptno%TYPE:=10;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
17:36:58 SCOTT@std1> 

獲取更新行數

08:48:43 SYS@std1> conn scott/tiger;
Connected.
08:48:49 SCOTT@std1> DECLARE
08:54:12   2    v_rows NUMBER;
08:54:12   3  BEGIN
08:54:12   4    UPDATE emp SET sal=30000 WHERE deptno=30;
08:54:12   5    v_rows:=SQL%ROWCOUNT;
08:54:12   6    dbms_output.put_line('更新了'||v_rows||'個雇員的工資');
08:54:12   7    ROLLBACK;
08:54:12   8  END;
08:54:13   9  /
更新了6個雇員的工資

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
08:54:14 SCOTT@std1> 

NO_DATA_FOUND 和 %NOTFOUND的區別: SELECT … INTO 語句觸發 NO_DATA_FOUND 當一個顯式游標的WHERE子句未找到時觸發%NOTFOUND 當UPDATE或DELETE 語句的WHERE 子句未找到時觸發 SQL%NOTFOUND 在提取迴圈中要用 %NOTFOUND 或%FOUND 來確定迴圈的退出條件,不要用 NO_DATA_FOUND 使用游標更新和刪除數據 游標修改和刪除操作是指在游標定位下,修改或刪除表中指定的數據行。這時,要求游標查詢語句中必須使用FOR UPDATE選項,以便在打開游標時鎖定游標結果集合在表中對應數據行的所有列和部分列 為了對正在處理(查詢)的行不被另外的用戶改動,ORACLE 提供一個 FOR UPDATE 子句來對所選擇的行進行鎖住。該需求迫使ORACLE鎖定游標結果集合的行,可以防止其他事務處理更新或刪除相同的行,直到您的事務處理提交或回退為止 語法:

ORA-0054 :resource busy  and  acquire with nowait specified.

>如果使用 FOR UPDATE 聲明游標,則可在DELETE和UPDATE 語句中使用WHERE CURRENT OF cursor_name子句,修改或刪除游標結果集合當前行對應的資料庫表中的數據行 例子

08:54:14 SCOTT@std1> DECLARE
09:21:38   2    v_deptno emp.deptno%TYPE:=&p_deptno;
09:21:38   3    CURSOR emp_cursor IS SELECT empno,sal FROM emp WHERE deptno=v_deptno FOR UPDATE NOWAIT;
09:21:38   4  BEGIN
09:21:38   5    FOR emp_record IN emp_cursor LOOP
09:21:38   6      IF emp_record.sal<1500 THEN 
09:21:38   7        UPDATE emp SET sal=1500 WHERE CURRENT OF emp_cursor;
09:21:38   8      END IF;
09:21:38   9    END LOOP;
09:21:38  10  END;
09:21:40  11  /
Enter value for p_deptno: 30
old   2:   v_deptno emp.deptno%TYPE:=&p_deptno;
new   2:   v_deptno emp.deptno%TYPE:=30;

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
09:21:43 SCOTT@std1>
09:36:06 SCOTT@std1> DECLARE
09:36:11   2    v_emp_record emp%ROWTYPE;
09:36:11   3    CURSOR c1 IS SELECT * FROM emp FOR UPDATE;
09:36:11   4  BEGIN
09:36:11   5    OPEN c1;
09:36:11   6    LOOP
09:36:11   7      FETCH c1 INTO v_emp_record;
09:36:12   8      EXIT WHEN c1%NOTFOUND;
09:36:12   9      IF v_emp_record.deptno=30 AND v_emp_record.job='SALESMAN' THEN 
09:36:12  10        UPDATE emp SET sal=20000 WHERE CURRENT OF c1;
09:36:12  11      END IF;
09:36:12  12    END LOOP;
09:36:12  13    CLOSE c1;
09:36:12  14  END;
09:36:12  15  /

PL/SQL procedure successfully completed.

Elapsed: 00:00:04.39
09:36:17 SCOTT@std1> 

游標變數 與游標一樣,游標變數也是一個指向多行查詢結果集合中當前數據行的指針 但與游標不同的是,游標變數是動態的,而游標是靜態的 游標只能與指定的查詢相連,即固定指向一個查詢的記憶體處理區域,而游標變數則可與不同的查詢語句相連,它可以指向不同查詢語句的記憶體處理區域(但不能同時指向多個記憶體處理區域,在某一時刻只能與一個查詢語句相連),只要這些查詢語句的返回類型相容即可 游標變數為一個指針,它屬於參照類型,所以在聲明游標變數類型之前必須先定義游標變數類型。在PL/SQL中,可以在塊、子程式和包的聲明區域內定義游標變數類型

TYPE ref_type_name IS REF CURSOR
 [ RETURN return_type];

其中:ref_type_name為新定義的游標變數類型名稱; return_type 為游標變數的返回值類型,它必須為記錄變數 在定義游標變數類型時,可以採用強類型定義和弱類型定義兩種。強類型定義必須指定游標變數的返回值類型,而弱類型定義則不說明返回值類型 簡單的來說:強類型的動態游標是指帶有return返回語句的,而弱類型的動態游標是指不帶return語句的(也即,弱類型的動態游標可以與任何查詢語句匹配,但是強類型的動態游標只能與特定的查詢語句匹配。) 聲明一個游標變數的兩個步驟: 步驟一:定義一個REF CURSOU數據類型,如: TYPE ref_cursor_type IS REF CURSOR; 步驟二:聲明一個該數據類型的游標變數,如: cv_ref REF_CURSOR_TYPE; 例子:創建兩個強類型定義游標變數和一個弱類型游標變數

DECLARE
  TYPE deptrecord IS RECORD(
  deptno dept.deptno%TYPE,
  dname dept.dname%TYPE,
  loc dept.loc%TYPE);
  TYPE depttype1 IS REF CURSOR RETURN dept%ROWTYPE;
  TYPE depttype2 IS REF CURSOR RETURN deptrecord;
  TYPE curtype IS REF CURSOR;
  dept1 depttype1;
  dept2 depttype2;
  cr1 curtype;

游標變數操作同樣是打開、提取、關閉 打開

OPEN {cursor_variable_name | :host_cursor_variable_name}
FOR select_statement;

其中:cursor_variable_name為游標變數,host_cursor_variable_name為PL/SQL主機環境(如OCI: ORACLE Call Interface,Pro*c 程式等)中聲明的游標變數。 OPEN…FOR 語句可以在關閉當前的游標變數之前重新打開游標變數,而不會導致CURSOR_ALREAD_OPEN異常錯誤。新打開游標變數時,前一個查詢的記憶體處理區將被釋放 提取

FETCH {cursor_variable_name | :host_cursor_variable_name}
INTO {variable [, variable]…| record_variable};

其中:cursor_variable_name和host_cursor_variable_name分別為游標變數和宿主游標變數名稱;variable和record_variable分別為普通變數和記錄變數名稱 關閉

CLOSE {cursor_variable_name | :host_cursor_variable_name}

其中:cursor_variable_name和host_cursor_variable_name分別為游標變數和宿主游標變數名稱,如果應用程式試圖關閉一個未打開的游標變數,則將導致INVALID_CURSOR異常錯誤。 例子:

09:36:17 SCOTT@std1> DECLARE
10:41:56   2    TYPE emp_job_rec IS RECORD(
10:41:56   3      empno emp.empno%TYPE,
10:41:56   4      ename emp.ename%TYPE,
10:41:56   5      job emp.job%TYPE
10:41:56   6    );
10:41:57   7    TYPE emp_job_refcur_type IS REF CURSOR RETURN emp_job_rec;
10:41:57   8    emp_refcur emp_job_refcur_type;
10:41:57   9    emp_job emp_job_rec;
10:41:57  10  BEGIN
10:41:57  11    OPEN emp_refcur FOR
10:41:57  12    SELECT empno,ename,job FROM emp ORDER BY deptno;
10:41:57  13    
10:41:57  14    FETCH emp_refcur INTO emp_job;
10:41:57  15    WHILE emp_refcur%FOUND LOOP
10:41:57  16      dbms_output.put_line(emp_job.empno||':'||emp_job.ename||'is a '||emp_job.job);
10:41:57  17      FETCH emp_refcur INTO emp_job;
10:41:57  18    END LOOP;
10:41:57  19    
10:41:57  20    CLOSE emp_refcur;
10:41:57  21  END;
10:41:58  22  /
7369:SMITHis a CLERK
7876:ADAMSis a CLERK
7566:JONESis a MANAGER
7788:SCOTTis a ANALYST
7902:FORDis a ANALYST
7900:JAMESis a CLERK
7844:TURNERis a SALESMAN
7654:MARTINis a SALESMAN
7521:WARDis a SALESMAN
7499:ALLENis a SALESMAN
7698:BLAKEis a MANAGER

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
10:41:58 SCOTT@std1> 
10:41:58 SCOTT@std1> DECLARE
11:38:42   2      Type refcur_t IS REF CURSOR;
11:38:42   3      Refcur refcur_t;
11:38:42   4      TYPE sample_rec_type IS RECORD (
11:38:42   5          Id number,
11:38:42   6          Description VARCHAR2 (30)
11:38:42   7      );
11:38:42   8      sample sample_rec_type;
11:38:42   9      selection varchar2(1) := UPPER (SUBSTR ('&tab', 1, 1));
11:38:42  10  BEGIN
11:38:42  11    IF selection='D' THEN 
11:38:42  12      OPEN refcur FOR
11:38:42  13        SELECT deptno,dname FROM dept;
11:38:42  14      dbms_output.put_line('Department Data');   
11:38:42  15     ELSE
11:38:42  16      OPEN refcur FOR
11:38:42  17         SELECT empno,ename FROM emp;
11:38:42  18       dbms_output.put_line('Employee Data');
11:38:42  19       RETURN;
11:38:42  20     END IF;
11:38:42  21     
11:38:42  22     dbms_output.put_line('----------------------------');
11:38:42  23     FETCH refcur INTO sample;
11:38:42  24     WHILE refcur%FOUND LOOP
11:38:42  25       dbms_output.put_line(sample.id||':'||sample.DESCRIPTION);
11:38:42  26       FETCH refcur INTO sample;
11:38:43  27     END LOOP;      
11:38:43  28     CLOSE refcur;
11:38:43  29  END;
11:38:43  30  /
Enter value for tab: D
old   9:     selection varchar2(1) := UPPER (SUBSTR ('&tab', 1, 1));
new   9:     selection varchar2(1) := UPPER (SUBSTR ('D', 1, 1));
Department Data
----------------------------
20:RESEARCH
30:SALES
40:OPERATIONS

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.00
11:38:46 SCOTT@std1> 
11:38:46 SCOTT@std1> DECLARE
12:04:38   2    TYPE emp_cursor_type IS REF CURSOR;
12:04:38   3    c1 emp_cursor_type;
12:04:38   4    v_emp_record emp%ROWTYPE;
12:04:38   5    v_reg_record dept%ROWTYPE;
12:04:38   6  BEGIN
12:04:38   7    OPEN c1 FOR SELECT * FROM emp WHERE deptno=20;
12:04:38   8    LOOP
12:04:38   9      FETCH c1 INTO v_emp_record;
12:04:38  10      EXIT WHEN c1%NOTFOUND;
12:04:38  11      dbms_output.put_line(v_emp_record.ename||'的雇佣日期:'||v_emp_record.hiredate);
12:04:38  12    END LOOP;
12:04:38  13    OPEN c1 FOR SELECT * FROM dept;
12:04:38  14    LOOP
12:04:38  15      FETCH c1 INTO v_reg_record;
12:04:38  16      EXIT WHEN c1%NOTFOUND;
12:04:38  17      dbms_output.put_line(v_reg_record.deptno||':'||v_reg_record.dname);
12:04:38  18    END LOOP;
12:04:38  19    CLOSE c1;
12:04:38  20  END;
12:04:38  21  /
SMITH的雇佣日期:17-DEC-80
JONES的雇佣日期:02-APR-81
SCOTT的雇佣日期:19-APR-87
ADAMS的雇佣日期:23-MAY-87
FORD的雇佣日期:03-DEC-81
20:RESEARCH
30:SALES
40:OPERATIONS

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.01
12:04:39 SCOTT@std1> 

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 環境描述: 雙節點RAC 資料庫:版本12.2.0.1 操作系統:linux 6.9 一、利用圖形化 準備好掛載點 cd /mkdir oggchown oracle:oinstall ogg chmod 775 /ogg 圖形化 asmca 我這裡是有問題,不知道什麼原因,做個記錄。後面手動掛載。 ...
  • 【查看mysql最大鏈接數】 MariaDB [(none)]> show variables like 'max_connections'; + + + | Variable_name | Value | + + + | max_connections | 151 | + + + + + + | ...
  • 記錄一下今天被坑了一下午的BUG 就從半個月前說起吧 當時..................................................................................................................... ... ...
  • Win7 Eclipse 搭建spark java1.8(lambda)環境:WordCount helloworld例子 ...
  • 列子: 一條語句實現將'a,b,c'拆分成'a','b','c'三條記錄。 一、REGEXP_SUBSTR函數的使用說明: Regexp_Substr(String,pattern,position,occurrence ,modifier )一共包含了五個參數: String:操作的字元串; pa ...
  • http://pic62.nipic.com/file/20150318/8684504_093611837474_2.jpg ...
  • 今天準備學習MongoDB,沒想到下載之後伺服器端啟動不了,記錄一下問題和處理過程 一.安裝 在Ubuntu中安裝還是很簡單,直接:sudo apt install mongodb 二.啟動 啟動MongoDB伺服器端:輸入mongod (或者使用 sudo service mongodb star ...
  • 在公司工作中,會遇到mysql資料庫存儲於某個人的電腦上,大家要想連接mysql服務,裝有mysql服務的電腦就必須開啟遠程連接。 其實不僅僅是區域網,只要你有資料庫所在伺服器的公網IP地址都能連上。 一. 授權 1. 連接資料庫 mysql -uroot -p 2.選擇系統庫,mysql use ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...