筆記081121 遊標(cursor)和存儲過程(procedure)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
創建一個遊標
SQL> edit;
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR mycur IS
3 SELECT * FROM STUDENT;
4 myrecode student%ROWTYPE;
5 BEGIN
6 OPEN mycur;
7 FETCH mycur INTO myrecode;
8 WHILE mycur%FOUND LOOP
9 DBMS_OUTPUT.PUT_LINE('the data is : '||myrecode.sno||myrecode.sname);
10 FETCH mycur INTO myrecode;
11 END LOOP;
12 CLOSE mycur;
13* END;
SQL> /
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUTPUT ON SIZE 10000
SQL> SET SERVEROUTPUT ON SIZE 10000
SQL> /
the data is : 01062401揍曄
the data is : 01062402黃費用
the data is : 01062403卡爛
the data is : 01062404住沒
the data is : 01062405沒豬
the data is : 01062406張故鄉
the data is : 01062407劉曄
the data is : 01062408張曄
the data is : 01062101揍曄
the data is : 01062102黃費用
the data is : 01062103卡爛
the data is : 01062104住沒
the data is : 01062105沒豬
the data is : 01062106張故鄉
the data is : 01062107劉曄
the data is : 01062108張曄
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
一個含有參數的遊標
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR mycur(ID varchar2) IS
3 SELECT SNAME FROM STUDENT WHERE SNO = ID;
4 myrecode STUDENT.SNAME%TYPE;
5 BEGIN
6 OPEN mycur('01062104');
7 LOOP
8 FETCH mycur INTO myrecode;
9 EXIT WHEN mycur%NOTFOUND;
10 DBMS_OUTPUT.PUT_LINE('SNAME IS '||myrecode);
11 END LOOP;
12 CLOSE mycur;
13* END;
SQL> /
SNAME IS 住沒
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL> DECLARE
2 CURSOR CUR_PARA(NAME VARCHAR2) IS
3 SELECT SNO FROM STUDENT WHERE SNAME = NAME ;
4 BEGIN
5 FOR CUR IN CUR_PARA('張故鄉') LOOP
6 DBMS_OUTPUT.PUT_LINE(CUR.SNO);
7 END LOOP;
8 END;
9 /
01062406
01062106
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL> DECLARE
2 SNAME STUDENT.SNAME%TYPE;
3 CURSOR CUR_PARA(ID CHAR) IS
4 SELECT SNAME FROM STUDENT WHERE SNO = ID;
5 BEGIN
6 IF CUR_PARA%ISOPEN THEN
7 DBMS_OUTPUT.PUT_LINE('*******************CURSOR IS OPEN *************');
8 ELSE
9 OPEN CUR_PARA('01062105');
10 END IF;
11 FETCH CUR_PARA INTO SNAME ;
12 CLOSE CUR_PARA;
13 DBMS_OUTPUT.PUT_LINE(SNAME);
14 END ;
15 /
沒豬
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ROWCOUNT
SQL> DECLARE
2 SNAME STUDENT.SNAME%TYPE;
3 CURSOR MYCUR IS
4 SELECT SNAME FROM STUDENT;
5 BEGIN
6 OPEN MYCUR;
7 LOOP
8 FETCH MYCUR INTO SNAME;
9 EXIT WHEN MYCUR%NOTFOUND OR MYCUR%NOTFOUND IS NULL;
10 DBMS_OUTPUT.PUT_LINE('ROWCOUNT: '||MYCUR%ROWCOUNT) ;
11 DBMS_OUTPUT.PUT_LINE(SNAME);
12 END LOOP;
13 CLOSE MYCUR;
14 END ;
15 /
ROWCOUNT: 1
揍曄
ROWCOUNT: 2
黃費用
ROWCOUNT: 3
卡爛
ROWCOUNT: 4
住沒
ROWCOUNT: 5
沒豬
ROWCOUNT: 6
張故鄉
ROWCOUNT: 7
劉曄
ROWCOUNT: 8
張曄
ROWCOUNT: 9
揍曄
ROWCOUNT: 10
黃費用
ROWCOUNT: 11
卡爛
ROWCOUNT: 12
住沒
ROWCOUNT: 13
沒豬
ROWCOUNT: 14
張故鄉
ROWCOUNT: 15
劉曄
ROWCOUNT: 16
張曄
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```````
遊標中使用UPDATE
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR CUR IS
3 SELECT SNAME FROM STUDENT FOR UPDATE;
4 TEXT STUDENT.SNAME%TYPE;
5 BEGIN
6 OPEN CUR;
7 FETCH CUR INTO TEXT;
8 WHILE CUR%FOUND LOOP
9 UPDATE STUDENT SET SNAME = SNAME ||'T' WHERE CURRENT OF CUR;
10 FETCH CUR INTO TEXT;
11 END LOOP;
12 CLOSE CUR;
13* END;
SQL> /
PL/SQL 過程已成功完成。
SQL> SELECT * FROM STUDENT;
SNO SNAME SSEX BIRTH SDEPT
---------------- -------------------- -------- -------------- ----------
01062401 揍曄T 男 02-3月 -88 2
01062402 黃費用T 女 05-3月 -89 2
01062403 卡爛T 男 02-6月 -88 2
01062404 住沒T 女 04-3月 -87 2
01062405 沒豬T 男 02-7月 -86
01062406 張故鄉T 女 03-3月 -84
01062407 劉曄T 男 02-8月 -84
01062408 張曄T 男 02-9月 -85
01062101 揍曄T 男 02-3月 -88 3
01062102 黃費用T 女 05-3月 -89 3
01062103 卡爛T 男 02-6月 -88 3
SNO SNAME SSEX BIRTH SDEPT
---------------- -------------------- -------- -------------- ----------
01062104 住沒T 女 04-3月 -87 3
01062105 沒豬T 男 02-7月 -86 3
01062106 張故鄉T 女 03-3月 -84 3
01062107 劉曄T 男 02-8月 -84 3
01062108 張曄T 男 02-9月 -85
已選擇16行。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``
隱式遊標
SQL> DECLARE
2 BEGIN
3 FOR CUR IN( SELECT SNAME FROM STUDENT) LOOP
4 DBMS_OUTPUT.PUT_LINE(CUR.SNAME);
5 END LOOP
6 ;
7 END ;
8 /
揍曄T
黃費用T
卡爛T
住沒T
沒豬T
張故鄉T
劉曄T
張曄T
揍曄T
黃費用T
卡爛T
住沒T
沒豬T
張故鄉T
劉曄T
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
創建一個存儲過程
SQL> EDIT
已寫入 file afiedt.buf
1 CREATE OR REPLACE PROCEDURE MYPROC(ID IN CHAR)
2 IS
3 NAME VARCHAR2(10);
4 BEGIN
5 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
6 DBMS_OUTPUT.PUT_LINE(NAME);
7* END ;
SQL> /
過程已創建。
SQL> EXECUTE MYPROC('01062108');
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SHOW ERRORS
SQL> edit
已寫入 file afiedt.buf
1 CREATE OR REPLACE PROCEDURE MYPROC(ID IN CHAR(8))
2 IS
3 NAME VARCHAR2(10);
4 BEGIN
5 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
6 DBMS_OUTPUT.PUT_LINE(NAME);
7* END ;
SQL> /
警告: 創建的過程帶有編譯錯誤。
SQL> show errors;
PROCEDURE MYPROC 出現錯誤:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/29 PLS-00103: 出現符號 "("在需要下列之一時:
:= ) , default
varying character large
符號 ":=" 被替換爲 "(" 後繼續。
SQL> show errors procedure myproc;
PROCEDURE MYPROC 出現錯誤:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/29 PLS-00103: 出現符號 "("在需要下列之一時:
:= ) , default
varying character large
符號 ":=" 被替換爲 "(" 後繼續。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
執行存儲過程
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 TID CHAR(8);
3 BEGIN
4 TID:= '01062108';
5 MYPROC(TID);
6* END;
SQL> /
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
有輸入有輸出的存儲過程
SQL> CREATE OR REPLACE PROCEDURE MYPROC2(ID CHAR , NAME OUT VARCHAR2)
2 IS
3 BEGIN
4 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
5 END;
6 /
過程已創建。
SQL> SAVE E:/oracle/myproce2.sql
已創建 file E:/oracle/myproce2.sql
SQL> DECLARE
2 TNAME VARCHAR2(10);
3 BEGIN
4 MYPROC2('01062108',TNAME);
5 DBMS_OUTPUT.PUT_LINE(TNAME);
6 END;
7 /
張曄T
PL/SQL 過程已成功完成。
創建一個遊標
SQL> edit;
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR mycur IS
3 SELECT * FROM STUDENT;
4 myrecode student%ROWTYPE;
5 BEGIN
6 OPEN mycur;
7 FETCH mycur INTO myrecode;
8 WHILE mycur%FOUND LOOP
9 DBMS_OUTPUT.PUT_LINE('the data is : '||myrecode.sno||myrecode.sname);
10 FETCH mycur INTO myrecode;
11 END LOOP;
12 CLOSE mycur;
13* END;
SQL> /
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SET SERVEROUTPUT ON SIZE 10000
SQL> SET SERVEROUTPUT ON SIZE 10000
SQL> /
the data is : 01062401揍曄
the data is : 01062402黃費用
the data is : 01062403卡爛
the data is : 01062404住沒
the data is : 01062405沒豬
the data is : 01062406張故鄉
the data is : 01062407劉曄
the data is : 01062408張曄
the data is : 01062101揍曄
the data is : 01062102黃費用
the data is : 01062103卡爛
the data is : 01062104住沒
the data is : 01062105沒豬
the data is : 01062106張故鄉
the data is : 01062107劉曄
the data is : 01062108張曄
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
一個含有參數的遊標
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR mycur(ID varchar2) IS
3 SELECT SNAME FROM STUDENT WHERE SNO = ID;
4 myrecode STUDENT.SNAME%TYPE;
5 BEGIN
6 OPEN mycur('01062104');
7 LOOP
8 FETCH mycur INTO myrecode;
9 EXIT WHEN mycur%NOTFOUND;
10 DBMS_OUTPUT.PUT_LINE('SNAME IS '||myrecode);
11 END LOOP;
12 CLOSE mycur;
13* END;
SQL> /
SNAME IS 住沒
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL> DECLARE
2 CURSOR CUR_PARA(NAME VARCHAR2) IS
3 SELECT SNO FROM STUDENT WHERE SNAME = NAME ;
4 BEGIN
5 FOR CUR IN CUR_PARA('張故鄉') LOOP
6 DBMS_OUTPUT.PUT_LINE(CUR.SNO);
7 END LOOP;
8 END;
9 /
01062406
01062106
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL> DECLARE
2 SNAME STUDENT.SNAME%TYPE;
3 CURSOR CUR_PARA(ID CHAR) IS
4 SELECT SNAME FROM STUDENT WHERE SNO = ID;
5 BEGIN
6 IF CUR_PARA%ISOPEN THEN
7 DBMS_OUTPUT.PUT_LINE('*******************CURSOR IS OPEN *************');
8 ELSE
9 OPEN CUR_PARA('01062105');
10 END IF;
11 FETCH CUR_PARA INTO SNAME ;
12 CLOSE CUR_PARA;
13 DBMS_OUTPUT.PUT_LINE(SNAME);
14 END ;
15 /
沒豬
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ROWCOUNT
SQL> DECLARE
2 SNAME STUDENT.SNAME%TYPE;
3 CURSOR MYCUR IS
4 SELECT SNAME FROM STUDENT;
5 BEGIN
6 OPEN MYCUR;
7 LOOP
8 FETCH MYCUR INTO SNAME;
9 EXIT WHEN MYCUR%NOTFOUND OR MYCUR%NOTFOUND IS NULL;
10 DBMS_OUTPUT.PUT_LINE('ROWCOUNT: '||MYCUR%ROWCOUNT) ;
11 DBMS_OUTPUT.PUT_LINE(SNAME);
12 END LOOP;
13 CLOSE MYCUR;
14 END ;
15 /
ROWCOUNT: 1
揍曄
ROWCOUNT: 2
黃費用
ROWCOUNT: 3
卡爛
ROWCOUNT: 4
住沒
ROWCOUNT: 5
沒豬
ROWCOUNT: 6
張故鄉
ROWCOUNT: 7
劉曄
ROWCOUNT: 8
張曄
ROWCOUNT: 9
揍曄
ROWCOUNT: 10
黃費用
ROWCOUNT: 11
卡爛
ROWCOUNT: 12
住沒
ROWCOUNT: 13
沒豬
ROWCOUNT: 14
張故鄉
ROWCOUNT: 15
劉曄
ROWCOUNT: 16
張曄
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```````
遊標中使用UPDATE
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 CURSOR CUR IS
3 SELECT SNAME FROM STUDENT FOR UPDATE;
4 TEXT STUDENT.SNAME%TYPE;
5 BEGIN
6 OPEN CUR;
7 FETCH CUR INTO TEXT;
8 WHILE CUR%FOUND LOOP
9 UPDATE STUDENT SET SNAME = SNAME ||'T' WHERE CURRENT OF CUR;
10 FETCH CUR INTO TEXT;
11 END LOOP;
12 CLOSE CUR;
13* END;
SQL> /
PL/SQL 過程已成功完成。
SQL> SELECT * FROM STUDENT;
SNO SNAME SSEX BIRTH SDEPT
---------------- -------------------- -------- -------------- ----------
01062401 揍曄T 男 02-3月 -88 2
01062402 黃費用T 女 05-3月 -89 2
01062403 卡爛T 男 02-6月 -88 2
01062404 住沒T 女 04-3月 -87 2
01062405 沒豬T 男 02-7月 -86
01062406 張故鄉T 女 03-3月 -84
01062407 劉曄T 男 02-8月 -84
01062408 張曄T 男 02-9月 -85
01062101 揍曄T 男 02-3月 -88 3
01062102 黃費用T 女 05-3月 -89 3
01062103 卡爛T 男 02-6月 -88 3
SNO SNAME SSEX BIRTH SDEPT
---------------- -------------------- -------- -------------- ----------
01062104 住沒T 女 04-3月 -87 3
01062105 沒豬T 男 02-7月 -86 3
01062106 張故鄉T 女 03-3月 -84 3
01062107 劉曄T 男 02-8月 -84 3
01062108 張曄T 男 02-9月 -85
已選擇16行。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``
隱式遊標
SQL> DECLARE
2 BEGIN
3 FOR CUR IN( SELECT SNAME FROM STUDENT) LOOP
4 DBMS_OUTPUT.PUT_LINE(CUR.SNAME);
5 END LOOP
6 ;
7 END ;
8 /
揍曄T
黃費用T
卡爛T
住沒T
沒豬T
張故鄉T
劉曄T
張曄T
揍曄T
黃費用T
卡爛T
住沒T
沒豬T
張故鄉T
劉曄T
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
創建一個存儲過程
SQL> EDIT
已寫入 file afiedt.buf
1 CREATE OR REPLACE PROCEDURE MYPROC(ID IN CHAR)
2 IS
3 NAME VARCHAR2(10);
4 BEGIN
5 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
6 DBMS_OUTPUT.PUT_LINE(NAME);
7* END ;
SQL> /
過程已創建。
SQL> EXECUTE MYPROC('01062108');
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SHOW ERRORS
SQL> edit
已寫入 file afiedt.buf
1 CREATE OR REPLACE PROCEDURE MYPROC(ID IN CHAR(8))
2 IS
3 NAME VARCHAR2(10);
4 BEGIN
5 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
6 DBMS_OUTPUT.PUT_LINE(NAME);
7* END ;
SQL> /
警告: 創建的過程帶有編譯錯誤。
SQL> show errors;
PROCEDURE MYPROC 出現錯誤:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/29 PLS-00103: 出現符號 "("在需要下列之一時:
:= ) , default
varying character large
符號 ":=" 被替換爲 "(" 後繼續。
SQL> show errors procedure myproc;
PROCEDURE MYPROC 出現錯誤:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/29 PLS-00103: 出現符號 "("在需要下列之一時:
:= ) , default
varying character large
符號 ":=" 被替換爲 "(" 後繼續。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
執行存儲過程
SQL> EDIT
已寫入 file afiedt.buf
1 DECLARE
2 TID CHAR(8);
3 BEGIN
4 TID:= '01062108';
5 MYPROC(TID);
6* END;
SQL> /
張曄T
PL/SQL 過程已成功完成。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~```
有輸入有輸出的存儲過程
SQL> CREATE OR REPLACE PROCEDURE MYPROC2(ID CHAR , NAME OUT VARCHAR2)
2 IS
3 BEGIN
4 SELECT SNAME INTO NAME FROM STUDENT WHERE SNO = ID;
5 END;
6 /
過程已創建。
SQL> SAVE E:/oracle/myproce2.sql
已創建 file E:/oracle/myproce2.sql
SQL> DECLARE
2 TNAME VARCHAR2(10);
3 BEGIN
4 MYPROC2('01062108',TNAME);
5 DBMS_OUTPUT.PUT_LINE(TNAME);
6 END;
7 /
張曄T
PL/SQL 過程已成功完成。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.