濮阳杆衣贸易有限公司

主頁 > 知識庫 > oracle 存儲過程詳細介紹(創(chuàng)建,刪除存儲過程,參數(shù)傳遞等)

oracle 存儲過程詳細介紹(創(chuàng)建,刪除存儲過程,參數(shù)傳遞等)

熱門標(biāo)簽:開封智能外呼系統(tǒng)廠家 美圖秀秀地圖標(biāo)注 word地圖標(biāo)注方向 征服眼公司地圖標(biāo)注 外呼線路外顯本地號碼 人工智能地圖標(biāo)注自己能做嗎 阿爾巴尼亞地圖標(biāo)注app 百度地圖標(biāo)注素材 征服者火車站地圖標(biāo)注

oracle 創(chuàng)建,刪除存儲過程,參數(shù)傳遞,創(chuàng)建,刪除存儲函數(shù),存儲過程和函數(shù)的查看,包,系統(tǒng)包

認識存儲過程和函數(shù)

存儲過程和函數(shù)也是一種PL/SQL塊,是存入數(shù)據(jù)庫的PL/SQL塊。但存儲過程和函數(shù)不同于已經(jīng)介紹過的PL/SQL程序,我們通常把PL/SQL程序稱為無名塊,而存儲過程和函數(shù)是以命名的方式存儲于數(shù)據(jù)庫中的。和PL/SQL程序相比,存儲過程有很多優(yōu)點,具體歸納如下:
* 存儲過程和函數(shù)以命名的數(shù)據(jù)庫對象形式存儲于數(shù)據(jù)庫當(dāng)中。存儲在數(shù)據(jù)庫中的優(yōu)點是很明顯的,因為代碼不保存在本地,用戶可以在任何客戶機上登錄到數(shù)據(jù)庫,并調(diào)用或修改代碼。
* 存儲過程和函數(shù)可由數(shù)據(jù)庫提供安全保證,要想使用存儲過程和函數(shù),需要有存儲過程和函數(shù)的所有者的授權(quán),只有被授權(quán)的用戶或創(chuàng)建者本身才能執(zhí)行存儲過程或調(diào)用函數(shù)。
* 存儲過程和函數(shù)的信息是寫入數(shù)據(jù)字典的,所以存儲過程可以看作是一個公用模塊,用戶編寫的PL/SQL程序或其他存儲過程都可以調(diào)用它(但存儲過程和函數(shù)不能調(diào)用PL/SQL程序)。一個重復(fù)使用的功能,可以設(shè)計成為存儲過程,比如:顯示一張工資統(tǒng)計表,可以設(shè)計成為存儲過程;一個經(jīng)常調(diào)用的計算,可以設(shè)計成為存儲函數(shù);根據(jù)雇員編號返回雇員的姓名,可以設(shè)計成存儲函數(shù)。
* 像其他高級語言的過程和函數(shù)一樣,可以傳遞參數(shù)給存儲過程或函數(shù),參數(shù)的傳遞也有多種方式。存儲過程可以有返回值,也可以沒有返回值,存儲過程的返回值必須通過參數(shù)帶回;函數(shù)有一定的數(shù)據(jù)類型,像其他的標(biāo)準函數(shù)一樣,我們可以通過對函數(shù)名的調(diào)用返回函數(shù)值。
   存儲過程和函數(shù)需要進行編譯,以排除語法錯誤,只有編譯通過才能調(diào)用。

創(chuàng)建和刪除存儲過程

創(chuàng)建存儲過程,需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統(tǒng)權(quán)限。該權(quán)限可由系統(tǒng)管理員授予。創(chuàng)建一個存儲過程的基本語句如下:
CREATE [OR REPLACE] PROCEDURE 存儲過程名[(參數(shù)[IN|OUT|IN OUT] 數(shù)據(jù)類型...)]
{AS|IS}
[說明部分]
BEGIN
可執(zhí)行部分
[EXCEPTION
錯誤處理部分]
END [過程名];

其中:
可選關(guān)鍵字OR REPLACE 表示如果存儲過程已經(jīng)存在,則用新的存儲過程覆蓋,通常用于存儲過程的重建。
參數(shù)部分用于定義多個參數(shù)(如果沒有參數(shù),就可以省略)。參數(shù)有三種形式:IN、OUT和IN OUT。如果沒有指明參數(shù)的形式,則默認為IN。
關(guān)鍵字AS也可以寫成IS,后跟過程的說明部分,可以在此定義過程的局部變量。
編寫存儲過程可以使用任何文本編輯器或直接在SQL*Plus環(huán)境下進行,編寫好的存儲過程必須要在SQL*Plus環(huán)境下進行編譯,生成編譯代碼,原代碼和編譯代碼在編譯過程中都會被存入數(shù)據(jù)庫。編譯成功的存儲過程就可以在Oracle環(huán)境下進行調(diào)用了。
一個存儲過程在不需要時可以刪除。刪除存儲過程的人是過程的創(chuàng)建者或者擁有DROP ANY PROCEDURE系統(tǒng)權(quán)限的人。刪除存儲過程的語法如下:

DROP PROCEDURE 存儲過程名;

如果要重新編譯一個存儲過程,則只能是過程的創(chuàng)建者或者擁有ALTER ANY PROCEDURE系統(tǒng)權(quán)限的人。語法如下:

ALTER PROCEDURE 存儲過程名 COMPILE;

執(zhí)行(或調(diào)用)存儲過程的人是過程的創(chuàng)建者或是擁有EXECUTE ANY PROCEDURE系統(tǒng)權(quán)限的人或是被擁有者授予EXECUTE權(quán)限的人。執(zhí)行的方法如下:
方法1:
EXECUTE 模式名.存儲過程名[(參數(shù)...)];
方法2:
BEGIN
模式名.存儲過程名[(參數(shù)...)];
END;
傳遞的參數(shù)必須與定義的參數(shù)類型、個數(shù)和順序一致(如果參數(shù)定義了默認值,則調(diào)用時可以省略參數(shù))。參數(shù)可以是變量、常量或表達式,用法參見下一節(jié)。
如果是調(diào)用本賬戶下的存儲過程,則模式名可以省略。要調(diào)用其他賬戶編寫的存儲過程,則模式名必須要添加。
以下是一個生成和調(diào)用簡單存儲過程的訓(xùn)練。注意要事先授予創(chuàng)建存儲過程的權(quán)限。

【訓(xùn)練1】  創(chuàng)建一個顯示雇員總?cè)藬?shù)的存儲過程。

步驟1:登錄SCOTT賬戶(或?qū)W生個人賬戶)。
步驟2:在SQL*Plus輸入?yún)^(qū)中,輸入以下存儲過程:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PROCEDURE EMP_COUNT
AS
V_TOTAL NUMBER(10);
BEGIN
 SELECT COUNT(*) INTO V_TOTAL FROM EMP;
 DBMS_OUTPUT.PUT_LINE('雇員總?cè)藬?shù)為:'||V_TOTAL);
END;

步驟3:按“執(zhí)行”按鈕進行編譯。
如果存在錯誤,就會顯示:
警告: 創(chuàng)建的過程帶有編譯錯誤。
如果存在錯誤,對腳本進行修改,直到?jīng)]有錯誤產(chǎn)生。
如果編譯結(jié)果正確,將顯示:

復(fù)制代碼 代碼如下:

過程已創(chuàng)建。

步驟4:調(diào)用存儲過程,在輸入?yún)^(qū)中輸入以下語句并執(zhí)行:

復(fù)制代碼 代碼如下:

EXECUTE EMP_COUNT;

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

雇員總?cè)藬?shù)為:14
PL/SQL 過程已成功完成。

說明:在該訓(xùn)練中,V_TOTAL變量是存儲過程定義的局部變量,用于接收查詢到的雇員總?cè)藬?shù)。
注意:在SQL*Plus中輸入存儲過程,按“執(zhí)行”按鈕是進行編譯,不是執(zhí)行存儲過程。
  如果在存儲過程中引用了其他用戶的對象,比如表,則必須有其他用戶授予的對象訪問權(quán)限。一個存儲過程一旦編譯成功,就可以由其他用戶或程序來引用。但存儲過程或函數(shù)的所有者必須授予其他用戶執(zhí)行該過程的權(quán)限。
存儲過程沒有參數(shù),在調(diào)用時,直接寫過程名即可。

【訓(xùn)練2】  在PL/SQL程序中調(diào)用存儲過程。

步驟1:登錄SCOTT賬戶。
步驟2:授權(quán)STUDENT賬戶使用該存儲過程,即在SQL*Plus輸入?yún)^(qū)中,輸入以下的命令:

復(fù)制代碼 代碼如下:

GRANT EXECUTE ON EMP_COUNT TO STUDENT

授權(quán)成功。

步驟3:登錄STUDENT賬戶,在SQL*Plus輸入?yún)^(qū)中輸入以下程序:

復(fù)制代碼 代碼如下:

SET SERVEROUTPUT ON
  BEGIN
  SCOTT.EMP_COUNT;
  END;

步驟4:執(zhí)行以上程序,結(jié)果為:

復(fù)制代碼 代碼如下:

雇員總?cè)藬?shù)為:14
  PL/SQL 過程已成功完成。nbsp;

說明:在本例中,存儲過程是由SCOTT賬戶創(chuàng)建的,STUDEN賬戶獲得SCOTT賬戶的授權(quán)后,才能調(diào)用該存儲過程。
  注意:在程序中調(diào)用存儲過程,使用了第二種語法。

【訓(xùn)練3】  編寫顯示雇員信息的存儲過程EMP_LIST,并引用EMP_COUNT存儲過程。

步驟1:在SQL*Plus輸入?yún)^(qū)中輸入并編譯以下存儲過程:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PROCEDURE EMP_LIST
  AS
    CURSOR emp_cursor IS
    SELECT empno,ename FROM emp;
  BEGIN
FOR Emp_record IN emp_cursor LOOP  
  DBMS_OUTPUT.PUT_LINE(Emp_record.empno||Emp_record.ename);
  END LOOP;
  EMP_COUNT;
  END;

執(zhí)行結(jié)果:

過程已創(chuàng)建。

步驟2:調(diào)用存儲過程,在輸入?yún)^(qū)中輸入以下語句并執(zhí)行:

復(fù)制代碼 代碼如下:

EXECUTE EMP_LIST

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

7369SMITH
7499ALLEN
7521WARD
7566JONES
      執(zhí)行結(jié)果:
  雇員總?cè)藬?shù)為:14
  PL/SQL 過程已成功完成。

說明:以上的EMP_LIST存儲過程中定義并使用了游標(biāo),用來循環(huán)顯示所有雇員的信息。然后調(diào)用已經(jīng)成功編譯的存儲過程EMP_COUNT,用來附加顯示雇員總?cè)藬?shù)。通過EXECUTE命令來執(zhí)行EMP_LIST存儲過程。

【練習(xí)1】編寫顯示部門信息的存儲過程DEPT_LIST,要求統(tǒng)計出部門個數(shù)。

參數(shù)傳遞

參數(shù)的作用是向存儲過程傳遞數(shù)據(jù),或從存儲過程獲得返回結(jié)果。正確的使用參數(shù)可以大大增加存儲過程的靈活性和通用性。
參數(shù)的類型有三種,如下所示。

復(fù)制代碼 代碼如下:

IN 定義一個輸入?yún)?shù)變量,用于傳遞參數(shù)給存儲過程
OUT 定義一個輸出參數(shù)變量,用于從存儲過程獲取數(shù)據(jù)
IN OUT 定義一個輸入、輸出參數(shù)變量,兼有以上兩者的功能

參數(shù)的定義形式和作用如下:
參數(shù)名 IN 數(shù)據(jù)類型 DEFAULT 值;
定義一個輸入?yún)?shù)變量,用于傳遞參數(shù)給存儲過程。在調(diào)用存儲過程時,主程序的實際參數(shù)可以是常量、有值變量或表達式等。DEFAULT 關(guān)鍵字為可選項,用來設(shè)定參數(shù)的默認值。如果在調(diào)用存儲過程時不指明參數(shù),則參數(shù)變量取默認值。在存儲過程中,輸入變量接收主程序傳遞的值,但不能對其進行賦值。
參數(shù)名 OUT 數(shù)據(jù)類型;
定義一個輸出參數(shù)變量,用于從存儲過程獲取數(shù)據(jù),即變量從存儲過程中返回值給主程序。
在調(diào)用存儲過程時,主程序的實際參數(shù)只能是一個變量,而不能是常量或表達式。在存儲過程中,參數(shù)變量只能被賦值而不能將其用于賦值,在存儲過程中必須給輸出變量至少賦值一次。
參數(shù)名 IN OUT 數(shù)據(jù)類型 DEFAULT 值;
定義一個輸入、輸出參數(shù)變量,兼有以上兩者的功能。在調(diào)用存儲過程時,主程序的實際參數(shù)只能是一個變量,而不能是常量或表達式。DEFAULT 關(guān)鍵字為可選項,用來設(shè)定參數(shù)的默認值。在存儲過程中,變量接收主程序傳遞的值,同時可以參加賦值運算,也可以對其進行賦值。在存儲過程中必須給變量至少賦值一次。
如果省略IN、OUT或IN OUT,則默認模式是IN。
【訓(xùn)練1】  編寫給雇員增加工資的存儲過程CHANGE_SALARY,通過IN類型的參數(shù)傳遞要增加工資的雇員編號和增加的工資額。
步驟1:登錄SCOTT賬戶。
  步驟2:在SQL*Plus輸入?yún)^(qū)中輸入以下存儲過程并執(zhí)行:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PROCEDURE CHANGE_SALARY(P_EMPNO IN NUMBER DEFAULT 7788,P_RAISE NUMBER DEFAULT 10)
  AS
   V_ENAME VARCHAR2(10);
V_SAL NUMBER(5);
  BEGIN
   SELECT ENAME,SAL INTO V_ENAME,V_SAL FROM EMP WHERE EMPNO=P_EMPNO;
   UPDATE EMP SET SAL=SAL+P_RAISE WHERE EMPNO=P_EMPNO;
   DBMS_OUTPUT.PUT_LINE('雇員'||V_ENAME||'的工資被改為'||TO_CHAR(V_SAL+P_RAISE));
COMMIT;
  EXCEPTION
   WHEN OTHERS THEN
   DBMS_OUTPUT.PUT_LINE('發(fā)生錯誤,修改失敗!');
   ROLLBACK;
  END;

執(zhí)行結(jié)果為:

過程已創(chuàng)建。

步驟3:調(diào)用存儲過程,在輸入?yún)^(qū)中輸入以下語句并執(zhí)行:

復(fù)制代碼 代碼如下:

EXECUTE CHANGE_SALARY(7788,80)

顯示結(jié)果為:

雇員SCOTT的工資被改為3080  

說明:從執(zhí)行結(jié)果可以看到,雇員SCOTT的工資已由原來的3000改為3080。
參數(shù)的值由調(diào)用者傳遞,傳遞的參數(shù)的個數(shù)、類型和順序應(yīng)該和定義的一致。如果順序不一致,可以采用以下調(diào)用方法。如上例,執(zhí)行語句可以改為:
 EXECUTE CHANGE_SALARY(P_RAISE=>80,P_EMPNO=>7788);
  可以看出傳遞參數(shù)的順序發(fā)生了變化,并且明確指出了參數(shù)名和要傳遞的值,=>運算符左側(cè)是參數(shù)名,右側(cè)是參數(shù)表達式,這種賦值方法的意義較清楚。
【練習(xí)1】創(chuàng)建插入雇員的存儲過程INSERT_EMP,并將雇員編號等作為參數(shù)。
在設(shè)計存儲過程的時候,也可以為參數(shù)設(shè)定默認值,這樣調(diào)用者就可以不傳遞或少傳遞參數(shù)了。
【訓(xùn)練2】  調(diào)用存儲過程CHANGE_SALARY,不傳遞參數(shù),使用默認參數(shù)值。
在SQL*Plus輸入?yún)^(qū)中輸入以下命令并執(zhí)行:

復(fù)制代碼 代碼如下:

EXECUTE CHANGE_SALARY 

顯示結(jié)果為:

雇員SCOTT的工資被改為3090  

說明:在存儲過程的調(diào)用中沒有傳遞參數(shù),而是采用了默認值7788和10,即默認雇員號為7788,增加的工資為10。
【訓(xùn)練3】  使用OUT類型的參數(shù)返回存儲過程的結(jié)果。
步驟1:登錄SCOTT賬戶。
步驟2:在SQL*Plus輸入?yún)^(qū)中輸入并編譯以下存儲過程:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PROCEDURE EMP_COUNT(P_TOTAL OUT NUMBER)
  AS
  BEGIN
  SELECT COUNT(*) INTO P_TOTAL FROM EMP;
  END;

執(zhí)行結(jié)果為:

1.過程已創(chuàng)建。 

步驟3:輸入以下程序并執(zhí)行:

復(fù)制代碼 代碼如下:

DECLARE
  V_EMPCOUNT NUMBER;
  BEGIN
  EMP_COUNT(V_EMPCOUNT);
  DBMS_OUTPUT.PUT_LINE('雇員總?cè)藬?shù)為:'||V_EMPCOUNT);
  END;

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

雇員總?cè)藬?shù)為:14
  PL/SQL 過程已成功完成。

 說明:在存儲過程中定義了OUT類型的參數(shù)P_TOTAL,在主程序調(diào)用該存儲過程時,傳遞了參數(shù)V_EMPCOUNT。在存儲過程中的SELECT...INTO...語句中對P_TOTAL進行賦值,賦值結(jié)果由V_EMPCOUNT變量帶回給主程序并顯示。
以上程序要覆蓋同名的EMP_COUNT存儲過程,如果不使用OR REPLACE選項,就會出現(xiàn)以下錯誤:

復(fù)制代碼 代碼如下:

ERROR 位于第 1 行:
  ORA-00955: 名稱已由現(xiàn)有對象使用。

【練習(xí)2】創(chuàng)建存儲過程,使用OUT類型參數(shù)獲得雇員經(jīng)理名。
【訓(xùn)練4】  使用IN OUT類型的參數(shù),給電話號碼增加區(qū)碼。
步驟1:登錄SCOTT賬戶。
步驟2:在SQL*Plus輸入?yún)^(qū)中輸入并編譯以下存儲過程:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PROCEDURE ADD_REGION(P_HPONE_NUM IN OUT VARCHAR2)
  AS
  BEGIN
   P_HPONE_NUM:='0755-'||P_HPONE_NUM;
  END;

執(zhí)行結(jié)果為:

過程已創(chuàng)建。 

步驟3:輸入以下程序并執(zhí)行:

復(fù)制代碼 代碼如下:

SET SERVEROUTPUT ON
DECLARE
V_PHONE_NUM VARCHAR2(15);
BEGIN
V_PHONE_NUM:='26731092';
ADD_REGION(V_PHONE_NUM);
DBMS_OUTPUT.PUT_LINE('新的電話號碼:'||V_PHONE_NUM);
END;

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

新的電話號碼:0755-26731092
  PL/SQL 過程已成功完成。

說明:變量V_HPONE_NUM既用來向存儲過程傳遞舊電話號碼,也用來向主程序返回新號碼。新的號碼在原來基礎(chǔ)上增加了區(qū)號0755和-。

創(chuàng)建和刪除存儲函數(shù)

  創(chuàng)建函數(shù),需要有CREATE PROCEDURE或CREATE ANY PROCEDURE的系統(tǒng)權(quán)限。該權(quán)限可由系統(tǒng)管理員授予。創(chuàng)建存儲函數(shù)的語法和創(chuàng)建存儲過程的類似,即
CREATE [OR REPLACE] FUNCTION 函數(shù)名[(參數(shù)[IN] 數(shù)據(jù)類型...)]
RETURN 數(shù)據(jù)類型
{AS|IS}
[說明部分]
BEGIN
可執(zhí)行部分
RETURN (表達式)
[EXCEPTION
    錯誤處理部分]
END [函數(shù)名];
其中,參數(shù)是可選的,但只能是IN類型(IN關(guān)鍵字可以省略)。
在定義部分的RETURN 數(shù)據(jù)類型,用來表示函數(shù)的數(shù)據(jù)類型,也就是返回值的類型,此部分不可省略。
在可執(zhí)行部分的RETURN(表達式),用來生成函數(shù)的返回值,其表達式的類型應(yīng)該和定義部分說明的函數(shù)返回值的數(shù)據(jù)類型一致。在函數(shù)的執(zhí)行部分可以有多個RETURN語句,但只有一個RETURN語句會被執(zhí)行,一旦執(zhí)行了RETURN語句,則函數(shù)結(jié)束并返回調(diào)用環(huán)境。
一個存儲函數(shù)在不需要時可以刪除,但刪除的人應(yīng)是函數(shù)的創(chuàng)建者或者是擁有DROP ANY PROCEDURE系統(tǒng)權(quán)限的人。其語法如下:
DROP FUNCTION 函數(shù)名;
重新編譯一個存儲函數(shù)時,編譯的人應(yīng)是函數(shù)的創(chuàng)建者或者擁有ALTER ANY PROCEDURE系統(tǒng)權(quán)限的人。重新編譯一個存儲函數(shù)的語法如下:
ALTER PROCEDURE 函數(shù)名 COMPILE;
函數(shù)的調(diào)用者應(yīng)是函數(shù)的創(chuàng)建者或擁有EXECUTE ANY PROCEDURE系統(tǒng)權(quán)限的人,或是被函數(shù)的擁有者授予了函數(shù)執(zhí)行權(quán)限的賬戶。函數(shù)的引用和存儲過程不同,函數(shù)要出現(xiàn)在程序體中,可以參加表達式的運算或單獨出現(xiàn)在表達式中,其形式如下:
變量名:=函數(shù)名(...)

【訓(xùn)練1】  創(chuàng)建一個通過雇員編號返回雇員名稱的函數(shù)GET_EMP_NAME。
步驟1:登錄SCOTT賬戶。
步驟2:在SQL*Plus輸入?yún)^(qū)中輸入以下存儲函數(shù)并編譯:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE FUNCTION GET_EMP_NAME(P_EMPNO NUMBER DEFAULT 7788)
  RETURN VARCHAR2
  AS
   V_ENAME VARCHAR2(10);
  BEGIN
   ELECT ENAME INTO V_ENAME FROM EMP WHERE EMPNO=P_EMPNO;
RETURN(V_ENAME);
EXCEPTION
 WHEN NO_DATA_FOUND THEN
  DBMS_OUTPUT.PUT_LINE('沒有該編號雇員!');
  RETURN (NULL);
 WHEN TOO_MANY_ROWS THEN
  DBMS_OUTPUT.PUT_LINE('有重復(fù)雇員編號!');
  RETURN (NULL);
 WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('發(fā)生其他錯誤!');
  RETURN (NULL);
END;

步驟3:調(diào)用該存儲函數(shù),輸入并執(zhí)行以下程序:

復(fù)制代碼 代碼如下:

BEGIN
    DBMS_OUTPUT.PUT_LINE('雇員7369的名稱是:'|| GET_EMP_NAME(7369));
    DBMS_OUTPUT.PUT_LINE('雇員7839的名稱是:'|| GET_EMP_NAME(7839));
  END;

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

雇員7369的名稱是:SMITH
  雇員7839的名稱是:KING
  PL/SQL 過程已成功完成。

說明:函數(shù)的調(diào)用直接出現(xiàn)在程序的DBMS_OUTPUT.PUT_LINE語句中,作為字符串表達式的一部分。如果輸入了錯誤的雇員編號,就會在函數(shù)的錯誤處理部分輸出錯誤信息。試修改雇員編號,重新運行調(diào)用部分。
【練習(xí)1】創(chuàng)建一個通過部門編號返回部門名稱的存儲函數(shù)GET_DEPT_NAME。
   【練習(xí)2】將函數(shù)的執(zhí)行權(quán)限授予STUDENT賬戶,然后登錄STUDENT賬戶調(diào)用。
存儲過程和函數(shù)的查看
可以通過對數(shù)據(jù)字典的訪問來查詢存儲過程或函數(shù)的有關(guān)信息,如果要查詢當(dāng)前用戶的存儲過程或函數(shù)的源代碼,可以通過對USER_SOURCE數(shù)據(jù)字典視圖的查詢得到。USER_SOURCE的結(jié)構(gòu)如下:

復(fù)制代碼 代碼如下:

DESCRIBE USER_SOURCE

結(jié)果為:

復(fù)制代碼 代碼如下:

名稱                                      是否為空? 類型
   ------------------------------------------------------------- ------------- -----------------------
 NAME                                             VARCHAR2(30)
 TYPE                                              VARCHAR2(12)
 LINE                                              NUMBER
 TEXT                                              VARCHAR2(4000)

說明:里面按行存放著過程或函數(shù)的腳本,NAME是過程或函數(shù)名,TYPE 代表類型(PROCEDURE或FUNCTION),LINE是行號,TEXT 為腳本。
【訓(xùn)練1】  查詢過程EMP_COUNT的腳本。
在SQL*Plus中輸入并執(zhí)行如下查詢:

復(fù)制代碼 代碼如下:

select TEXT  from user_source WHERE NAME='EMP_COUNT';

結(jié)果為:

復(fù)制代碼 代碼如下:

TEXT
--------------------------------------------------------------------------------
PROCEDURE EMP_COUNT(P_TOTAL OUT NUMBER)
AS
BEGIN
 SELECT COUNT(*) INTO P_TOTAL FROM EMP;
END;

【訓(xùn)練2】  查詢過程GET_EMP_NAME的參數(shù)。
在SQL*Plus中輸入并執(zhí)行如下查詢:

復(fù)制代碼 代碼如下:

DESCRIBE GET_EMP_NAME

結(jié)果為:

復(fù)制代碼 代碼如下:

FUNCTION GET_EMP_NAME RETURNS VARCHAR2
  參數(shù)名稱            類型          輸入/輸出默認值?
  ----------------------------------------- ----------------------------------- ----------------- -------------
   P_EMPNO             NUMBER(4) IN     DEFAULT

【訓(xùn)練3】  在發(fā)生編譯錯誤時,顯示錯誤。

復(fù)制代碼 代碼如下:

SHOW ERRORS

以下是一段編譯錯誤顯示:

復(fù)制代碼 代碼如下:

LINE/COL ERROR
  ------------- -----------------------------------------------------------------
  4/2       PL/SQL: SQL Statement ignored
  4/36      PLS-00201: 必須說明標(biāo)識符 'EMPP'

說明:查詢一個存儲過程或函數(shù)是否是有效狀態(tài)(即編譯成功),可以使用數(shù)據(jù)字典USER_OBJECTS的STATUS列。
【訓(xùn)練4】  查詢EMP_LIST存儲過程是否可用:

復(fù)制代碼 代碼如下:

SELECT STATUS FROM USER_OBJECTS WHERE OBJECT_NAME='EMP_LIST';

結(jié)果為:

復(fù)制代碼 代碼如下:

STATUS
  ------------
  VALID

說明:VALID表示該存儲過程有效(即通過編譯),INVALID表示存儲過程無效或需要重新編譯。當(dāng)Oracle調(diào)用一個無效的存儲過程或函數(shù)時,首先試圖對其進行編譯,如果編譯成功則將狀態(tài)置成VALID并執(zhí)行,否則給出錯誤信息。
當(dāng)一個存儲過程編譯成功,狀態(tài)變?yōu)閂ALID,會不會在某些情況下變成INVALID。結(jié)論是完全可能的。比如一個存儲過程中包含對表的查詢,如果表被修改或刪除,存儲過程就會變成無效INVALID。所以要注意存儲過程和函數(shù)對其他對象的依賴關(guān)系。
如果要檢查存儲過程或函數(shù)的依賴性,可以通過查詢數(shù)據(jù)字典USER_DENPENDENCIES來確定,該表結(jié)構(gòu)如下:

復(fù)制代碼 代碼如下:

DESCRIBE USER_DEPENDENCIES;

結(jié)果:

復(fù)制代碼 代碼如下:

名稱                     是否為空? 類型
   -------------------------------------------------------------- ------------- ----------------------------
   NAME            NOT NULL VARCHAR2(30)
   TYPE                       VARCHAR2(12)
  REFERENCED_OWNER                              VARCHAR2(30)
 REFERENCED_NAME                               VARCHAR2(64)
 REFERENCED_TYPE                                VARCHAR2(12)
REFERENCED_LINK_NAME                         VARCHAR2(128)
   SCHEMAID                                        NUMBER
   DEPENDENCY_TYPE                                VARCHAR2(4)

說明:NAME為實體名,TYPE為實體類型,REFERENCED_OWNER為涉及到的實體擁有者賬戶,REFERENCED_NAME為涉及到的實體名,REFERENCED_TYPE 為涉及到的實體類型。
【訓(xùn)練5】  查詢EMP_LIST存儲過程的依賴性。

復(fù)制代碼 代碼如下:

SELECT REFERENCED_NAME,REFERENCED_TYPE FROM USER_DEPENDENCIES WHERE NAME='EMP_LIST';

執(zhí)行結(jié)果:

復(fù)制代碼 代碼如下:

REFERENCED_NAME                                         REFERENCED_TYPE
  ------------------------------------------------------------------------------------------ ----------------------------
STANDARD                                               PACKAGE
  SYS_STUB_FOR_PURITY_ANALYSIS                           PACKAGE
  DBMS_OUTPUT                                              PACKAGE
  DBMS_OUTPUT                                             SYNONYM
DBMS_OUTPUT                      NON-EXISTENT
  EMP                                                        TABLE
  EMP_COUNT                                                 PROCEDURE

說明:可以看出存儲過程EMP_LIST依賴一些系統(tǒng)包、EMP表和EMP_COUNT存儲過程。如果刪除了EMP表或EMP_COUNT存儲過程,EMP_LIST將變成無效。
還有一種情況需要我們注意:如果一個用戶A被授予執(zhí)行屬于用戶B的一個存儲過程的權(quán)限,在用戶B的存儲過程中,訪問到用戶C的表,用戶B被授予訪問用戶C的表的權(quán)限,但用戶A沒有被授予訪問用戶C表的權(quán)限,那么用戶A調(diào)用用戶B的存儲過程是失敗的還是成功的呢?答案是成功的。如果讀者有興趣,不妨進行一下實際測試。


包的概念和組成

包是用來存儲相關(guān)程序結(jié)構(gòu)的對象,它存儲于數(shù)據(jù)字典中。包由兩個分離的部分組成:包頭(PACKAGE)和包體(PACKAGE BODY)。包頭是包的說明部分,是對外的操作接口,對應(yīng)用是可見的;包體是包的代碼和實現(xiàn)部分,對應(yīng)用來說是不可見的黑盒。
包中可以包含的程序結(jié)構(gòu)如下所示。

復(fù)制代碼 代碼如下:

過程(PROCUDURE) 帶參數(shù)的命名的程序模塊
函數(shù)(FUNCTION) 帶參數(shù)、具有返回值的命名的程序模塊
變量(VARIABLE) 存儲變化的量的存儲單元
常量(CONSTANT) 存儲不變的量的存儲單元
游標(biāo)(CURSOR) 用戶定義的數(shù)據(jù)操作緩存區(qū),在可執(zhí)行部分使用
類型(TYPE) 用戶定義的新的結(jié)構(gòu)類型
異常(EXCEPTION) 在標(biāo)準包中定義或由用戶自定義,用于處理程序錯誤

說明部分可以出現(xiàn)在包的三個不同的部分:出現(xiàn)在包頭中的稱為公有元素,出現(xiàn)在包體中的稱為私有元素,出現(xiàn)在包體的過程(或函數(shù))中的稱為局部變量。它們的性質(zhì)有所不同,如下所示。

復(fù)制代碼 代碼如下:

公有元素(PUBLIC) 在包頭中說明,在包體中具體定義 在包外可見并可以訪問,對整個應(yīng)用的全過程有效
私有元素(PRIVATE) 在包體的說明部分說明 只能被包內(nèi)部的其他部分訪問
局部變量(LOCAL) 在過程或函數(shù)的說明部分說明 只能在定義變量的過程或函數(shù)中使用

在包體中出現(xiàn)的過程或函數(shù),如果需要對外公用,就必須在包頭中說明,包頭中的說明應(yīng)該和包體中的說明一致。
包有以下優(yōu)點:
* 包可以方便地將存儲過程和函數(shù)組織到一起,每個包又是相互獨立的。在不同的包中,過程、函數(shù)都可以重名,這解決了在同一個用戶環(huán)境中命名的沖突問題。
* 包增強了對存儲過程和函數(shù)的安全管理,對整個包的訪問權(quán)只需一次授予。
  * 在同一個會話中,公用變量的值將被保留,直到會話結(jié)束。
* 區(qū)分了公有過程和私有過程,包體的私有過程增加了過程和函數(shù)的保密性。
* 包在被首次調(diào)用時,就作為一個整體被全部調(diào)入內(nèi)存,減少了多次訪問過程或函數(shù)的I/O次數(shù)。
創(chuàng)建包和包體
包由包頭和包體兩部分組成,包的創(chuàng)建應(yīng)該先創(chuàng)建包頭部分,然后創(chuàng)建包體部分。創(chuàng)建、刪除和編譯包的權(quán)限同創(chuàng)建、刪除和編譯存儲過程的權(quán)限相同。
創(chuàng)建包頭的簡要語句如下:
CREATE [OR REPLACE] PACKAGE 包名
{IS|AS}
公有變量定義
公有類型定義
公有游標(biāo)定義
公有異常定義
函數(shù)說明
過程說明
END;
創(chuàng)建包體的簡要語法如下:
CREATE [OR REPLACE] PACKAGE BODY 包名
{IS|AS}
私有變量定義
私有類型定義
私有游標(biāo)定義
私有異常定義
函數(shù)定義
過程定義
END;
包的其他操作命令包括:
刪除包頭:
DROP PACKAGE 包頭名
刪除包體:
DROP PACKAGE BODY 包體名
重新編譯包頭:
ALTER PACKAGE 包名 COMPILE PACKAGE
重新編譯包體:
ALTER PACKAGE 包名 COMPILE PACKAGE BODY
在包頭中說明的對象可以在包外調(diào)用,調(diào)用的方法和調(diào)用單獨的過程或函數(shù)的方法基本相同,惟一的區(qū)別就是要在調(diào)用的過程或函數(shù)名前加上包的名字(中間用“.”分隔)。但要注意,不同的會話將單獨對包的公用變量進行初始化,所以不同的會話對包的調(diào)用屬于不同的應(yīng)用。
系統(tǒng)包
Oracle預(yù)定義了很多標(biāo)準的系統(tǒng)包,這些包可以在應(yīng)用中直接使用,比如在訓(xùn)練中我們使用的DBMS_OUTPUT包,就是系統(tǒng)包。PUT_LINE是該包的一個函數(shù)。常用系統(tǒng)包下所示。

復(fù)制代碼 代碼如下:

DBMS_OUTPUT 在SQL*Plus環(huán)境下輸出信息
DBMS_DDL 編譯過程函數(shù)和包
DBMS_SESSION 改變用戶的會話,初始化包等
DBMS_TRANSACTION 控制數(shù)據(jù)庫事務(wù)
DBMS_MAIL 連接Oracle*Mail
DBMS_LOCK 進行復(fù)雜的鎖機制管理
DBMS_ALERT 識別數(shù)據(jù)庫事件告警
DBMS_PIPE 通過管道在會話間傳遞信息
DBMS_JOB 管理Oracle的作業(yè)
DBMS_LOB 操縱大對象
DBMS_SQL 執(zhí)行動態(tài)SQL語句

包的應(yīng)用

在SQL*Plus環(huán)境下,包和包體可以分別編譯,也可以一起編譯。如果分別編譯,則要先編譯包頭,后編譯包體。如果在一起編譯,則包頭寫在前,包體在后,中間用“/”分隔。
可以將已經(jīng)存在的存儲過程或函數(shù)添加到包中,方法是去掉過程或函數(shù)創(chuàng)建語句的CREATE OR REPLACE部分,將存儲過程或函數(shù)復(fù)制到包體中 ,然后重新編譯即可。
   如果需要將私有過程或函數(shù)變成共有過程或函數(shù)的話,將過程或函數(shù)說明部分復(fù)制到包頭說明部分,然后重新編譯就可以了。
【訓(xùn)練1】  創(chuàng)建管理雇員信息的包EMPLOYE,它具有從EMP表獲得雇員信息,修改雇員名稱,修改雇員工資和寫回EMP表的功能。
步驟1:登錄SCOTT賬戶,輸入以下代碼并編譯:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PACKAGE EMPLOYE --包頭部分
  IS
 PROCEDURE SHOW_DETAIL;
 PROCEDURE GET_EMPLOYE(P_EMPNO NUMBER);
 PROCEDURE SAVE_EMPLOYE;
 PROCEDURE CHANGE_NAME(P_NEWNAME VARCHAR2);
PROCEDURE CHANGE_SAL(P_NEWSAL NUMBER);
  END EMPLOYE;
  /
  CREATE OR REPLACE PACKAGE BODY EMPLOYE --包體部分
  IS
 EMPLOYE EMP%ROWTYPE;
  -------------- 顯示雇員信息 ---------------
  PROCEDURE SHOW_DETAIL
   AS
   BEGIN
DBMS_OUTPUT.PUT_LINE(‘----- 雇員信息 -----'); 
    DBMS_OUTPUT.PUT_LINE('雇員編號:'||EMPLOYE.EMPNO);
    DBMS_OUTPUT.PUT_LINE('雇員名稱:'||EMPLOYE.ENAME);
    DBMS_OUTPUT.PUT_LINE('雇員職務(wù):'||EMPLOYE.JOB);
    DBMS_OUTPUT.PUT_LINE('雇員工資:'||EMPLOYE.SAL);
    DBMS_OUTPUT.PUT_LINE('部門編號:'||EMPLOYE.DEPTNO);
   END SHOW_DETAIL;
----------------- 從EMP表取得一個雇員 --------------------
   PROCEDURE GET_EMPLOYE(P_EMPNO NUMBER)
   AS
   BEGIN
    SELECT * INTO EMPLOYE FROM EMP WHERE  EMPNO=P_EMPNO;
    DBMS_OUTPUT.PUT_LINE('獲取雇員'||EMPLOYE.ENAME||'信息成功');
   EXCEPTION
    WHEN OTHERS THEN
     DBMS_OUTPUT.PUT_LINE('獲取雇員信息發(fā)生錯誤!');
   END GET_EMPLOYE;
---------------------- 保存雇員到EMP表 --------------------------
   PROCEDURE SAVE_EMPLOYE
   AS
   BEGIN
    UPDATE EMP SET ENAME=EMPLOYE.ENAME, SAL=EMPLOYE.SAL WHERE EMPNO=
 EMPLOYE.EMPNO;
   DBMS_OUTPUT.PUT_LINE('雇員信息保存完成!');
   END SAVE_EMPLOYE;
---------------------------- 修改雇員名稱 ------------------------------
   PROCEDURE CHANGE_NAME(P_NEWNAME VARCHAR2)
   AS
   BEGIN
    EMPLOYE.ENAME:=P_NEWNAME;
    DBMS_OUTPUT.PUT_LINE('修改名稱完成!');
   END CHANGE_NAME;
---------------------------- 修改雇員工資 --------------------------
   PROCEDURE CHANGE_SAL(P_NEWSAL NUMBER)
   AS
   BEGIN
    EMPLOYE.SAL:=P_NEWSAL;
    DBMS_OUTPUT.PUT_LINE('修改工資完成!');
   END CHANGE_SAL;
  END EMPLOYE;


步驟2:獲取雇員7788的信息:

復(fù)制代碼 代碼如下:

SET SERVEROUTPUT ON
  EXECUTE EMPLOYE.GET_EMPLOYE(7788);

結(jié)果為:

復(fù)制代碼 代碼如下:

獲取雇員SCOTT信息成功
  PL/SQL 過程已成功完成。

步驟3:顯示雇員信息:

復(fù)制代碼 代碼如下:

EXECUTE EMPLOYE.SHOW_DETAIL;

結(jié)果為:

復(fù)制代碼 代碼如下:

------------------ 雇員信息 ------------------
  雇員編號:7788
  雇員名稱:SCOTT
  雇員職務(wù):ANALYST
  雇員工資:3000
  部門編號:20
  PL/SQL 過程已成功完成。

步驟4:修改雇員工資:

復(fù)制代碼 代碼如下:

EXECUTE EMPLOYE.CHANGE_SAL(3800);

結(jié)果為:

復(fù)制代碼 代碼如下:

修改工資完成!
  PL/SQL 過程已成功完成。

步驟5:將修改的雇員信息存入EMP表

復(fù)制代碼 代碼如下:

EXECUTE EMPLOYE.SAVE_EMPLOYE;

結(jié)果為:

復(fù)制代碼 代碼如下:

雇員信息保存完成!
  PL/SQL 過程已成功完成。

說明:該包完成將EMP表中的某個雇員的信息取入內(nèi)存記錄變量,在記錄變量中進行修改編輯,在確認顯示信息正確后寫回EMP表的功能。記錄變量EMPLOYE用來存儲取得的雇員信息,定義為私有變量,只能被包的內(nèi)部模塊訪問。
  【練習(xí)1】為包增加修改雇員職務(wù)和部門編號的功能。

階段訓(xùn)練
下面的訓(xùn)練通過定義和創(chuàng)建完整的包EMP_PK并綜合運用本章的知識,完成對雇員表的插入、刪除等功能,包中的主要元素解釋如下所示。

復(fù)制代碼 代碼如下:

程序結(jié)構(gòu) 類  型 說    明
V_EMP_COUNT 公有變量 跟蹤雇員的總?cè)藬?shù)變化,插入、刪除雇員的同時修改該變量的值
INIT 公有過程 對包進行初始化,初始化雇員人數(shù)和工資修改的上、下限
LIST_EMP 公有過程 顯示雇員列表
INSERT_EMP 公有過程 通過編號插入新雇員
DELETE_EMP 公有過程 通過編號刪除雇員
CHANGE_EMP_SAL 公有過程 通過編號修改雇員工資
V_MESSAGE 私有變量 存放準備輸出的信息
C_MAX_SAL 私有變量 對工資修改的上限
C_MIN_SAL 私有變量 對工資修改的下限
SHOW_MESSAGE 私有過程 顯示私有變量V_MESSAGE中的信息
EXIST_EMP 私有函數(shù) 判斷某個編號的雇員是否存在,該函數(shù)被INSERT_EMP、DELETE_EMP和CHANGE_EMP_SAL等過程調(diào)用

【訓(xùn)練1】  完整的雇員包EMP_PK的創(chuàng)建和應(yīng)用。
步驟1:在SQL*Plus中登錄SCOTT賬戶,輸入以下包頭和包體部分,按“執(zhí)行”按鈕編譯:

復(fù)制代碼 代碼如下:

CREATE OR REPLACE PACKAGE EMP_PK
  --包頭部分
  IS
   V_EMP_COUNT NUMBER(5);     
  --雇員人數(shù)
   PROCEDURE INIT(P_MAX NUMBER,P_MIN NUMBER);  --初始化
   PROCEDURE LIST_EMP;      
  --顯示雇員列表
PROCEDURE INSERT_EMP(P_EMPNO   NUMBER,P_ENAMEVARCHAR2,P_JOB VARCHAR2,
   P_SAL NUMBER);       
  --插入雇員
  PROCEDURE DELETE_EMP(P_EMPNO NUMBER);   --刪除雇員
   PROCEDURE CHANGE_EMP_SAL(P_EMPNO NUMBER,P_SAL NUMBER);
  --修改雇員工資
  END EMP_PK;
  /CREATE OR REPLACE PACKAGE BODY EMP_PK
   --包體部分
  IS
   V_MESSAGE VARCHAR2(50); --顯示信息
V_MAX_SAL NUMBER(7); --工資上限
   V_MIN_SAL NUMBER(7); --工資下限
   FUNCTION EXIST_EMP(P_EMPNO NUMBER)  RETURN  BOOLEAN; --判斷雇員是否存在函數(shù)
   PROCEDURE SHOW_MESSAGE; --顯示信息過程
  ------------------------------- 初始化過程 ----------------------------
   PROCEDURE INIT(P_MAX NUMBER,P_MIN NUMBER)
  IS
  BEGIN
      SELECT COUNT(*) INTO V_EMP_COUNT FROM EMP;
V_MAX_SAL:=P_MAX;
    V_MIN_SAL:=P_MIN;
    V_MESSAGE:='初始化過程已經(jīng)完成!';
    SHOW_MESSAGE;
   END INIT;
---------------------------- 顯示雇員列表過程 ---------------------
  PROCEDURE LIST_EMP
   IS
   BEGIN
DBMS_OUTPUT.PUT_LINE('姓名       職務(wù)      工資');
    FOR emp_rec IN (SELECT * FROM EMP)
    LOOP
  DBMS_OUTPUT.PUT_LINE(RPAD(emp_rec.ename,10,'')||RPAD(emp_rec.job,10,' ')||TO_CHAR(emp_rec.sal));
    END LOOP;
    DBMS_OUTPUT.PUT_LINE('雇員總?cè)藬?shù)'||V_EMP_COUNT);
   END LIST_EMP;
----------------------------- 插入雇員過程 -----------------------------
   PROCEDUREINSERT_EMP(P_EMPNO  NUMBER,P_ENAMEVARCHAR2,P_JOB  VARCHAR2,P_SAL NUMBER)
   IS
   BEGIN
   IF NOT EXIST_EMP(P_EMPNO) THEN
    INSERT INTO EMP(EMPNO,ENAME,JOB,SAL)   VALUES(P_EMPNO,P_ENAME,P_JOB,P_SAL);
  COMMIT; 
     V_EMP_COUNT:=V_EMP_COUNT+1;
    V_MESSAGE:='雇員'||P_EMPNO||'已插入!';
    ELSE
V_MESSAGE:='雇員'||P_EMPNO||'已存在,不能插入!';
   END IF;
   SHOW_MESSAGE;
  EXCEPTION
   WHEN OTHERS THEN
    V_MESSAGE:='雇員'||P_EMPNO||'插入失敗!';
    SHOW_MESSAGE;
  END INSERT_EMP;
--------------------------- 刪除雇員過程 --------------------
   PROCEDURE DELETE_EMP(P_EMPNO NUMBER)
   IS
   BEGIN
    IF EXIST_EMP(P_EMPNO) THEN
     DELETE FROM EMP WHERE EMPNO=P_EMPNO;
     COMMIT;
     V_EMP_COUNT:=V_EMP_COUNT-1;
     V_MESSAGE:='雇員'||P_EMPNO||'已刪除!';
    ELSE
V_MESSAGE:='雇員'||P_EMPNO||'不存在,不能刪除!';
   END IF;
   SHOW_MESSAGE;
  EXCEPTION
   WHEN OTHERS THEN
    V_MESSAGE:='雇員'||P_EMPNO||'刪除失敗!';
    SHOW_MESSAGE;
  END DELETE_EMP;
--------------------------------------- 修改雇員工資過程 ------------------------------------
   PROCEDURE CHANGE_EMP_SAL(P_EMPNO NUMBER,P_SAL NUMBER)
   IS
   BEGIN
    IF (P_SAL>V_MAX_SAL OR P_SALV_MIN_SAL) THEN
     V_MESSAGE:='工資超出修改范圍!';
    ELSIF NOT EXIST_EMP(P_EMPNO) THEN
     V_MESSAGE:='雇員'||P_EMPNO||'不存在,不能修改工資!';
ELSE
     UPDATE EMP SET SAL=P_SAL WHERE EMPNO=P_EMPNO;
     COMMIT;
     V_MESSAGE:='雇員'||P_EMPNO||'工資已經(jīng)修改!';
    END IF;
    SHOW_MESSAGE;
   EXCEPTION
    WHEN OTHERS THEN
     V_MESSAGE:='雇員'||P_EMPNO||'工資修改失敗!';
     SHOW_MESSAGE;
   END CHANGE_EMP_SAL;
---------------------------- 顯示信息過程 ----------------------------
   PROCEDURE SHOW_MESSAGE
   IS
   BEGIN
    DBMS_OUTPUT.PUT_LINE('提示信息:'||V_MESSAGE);
   END SHOW_MESSAGE;
------------------------ 判斷雇員是否存在函數(shù) -------------------
   FUNCTION EXIST_EMP(P_EMPNO NUMBER)
   RETURN BOOLEAN
   IS
    V_NUM NUMBER; --局部變量
   BEGIN
    SELECT COUNT(*) INTO V_NUM FROM EMP WHERE EMPNO=P_EMPNO;
IF V_NUM=1 THEN
     RETURN TRUE;
    ELSE
     RETURN FALSE;
    END IF;
   END EXIST_EMP;
  -----------------------------
  END EMP_PK;

結(jié)果為:

1.程序包已創(chuàng)建。  
2.        程序包主體已創(chuàng)建。 

步驟2:初始化包:

復(fù)制代碼 代碼如下:

SET SERVEROUTPUT ON
EXECUTE EMP_PK.INIT(6000,600);

顯示為:

提示信息:初始化過程已經(jīng)完成! 

步驟3:顯示雇員列表:

復(fù)制代碼 代碼如下:

EXECUTE EMP_PK.LIST_EMP;

顯示為:

復(fù)制代碼 代碼如下:

姓名        職務(wù)       工資
  SMITH      CLERK      1560
  ALLEN      SALESMAN   1936
  WARD      SALESMAN   1830
  JONES      MANAGER    2975
  ...
  雇員總?cè)藬?shù):14
  PL/SQL 過程已成功完成。

步驟4:插入一個新記錄:

復(fù)制代碼 代碼如下:

EXECUTE EMP_PK.INSERT_EMP(8001,'小王','CLERK',1000);

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

提示信息:雇員8001已插入!
PL/SQL 過程已成功完成。

步驟5:通過全局變量V_EMP_COUNT查看雇員人數(shù):

復(fù)制代碼 代碼如下:

BEGIN
DBMS_OUTPUT.PUT_LINE(EMP_PK.V_EMP_COUNT);
END;

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

15
PL/SQL 過程已成功完成。

步驟6:刪除新插入記錄:

復(fù)制代碼 代碼如下:

EXECUTE EMP_PK.DELETE_EMP(8001);

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

提示信息:雇員8001已刪除!
  PL/SQL 過程已成功完成。

再次刪除該雇員:

復(fù)制代碼 代碼如下:

EXECUTE EMP_PK.DELETE_EMP(8001);

結(jié)果為:

復(fù)制代碼 代碼如下:

提示信息:雇員8001不存在,不能刪除!

步驟7:修改雇員工資:

復(fù)制代碼 代碼如下:

EXECUTE EMP_PK.CHANGE_EMP_SAL(7788,8000);

顯示結(jié)果為:

復(fù)制代碼 代碼如下:

提示信息:工資超出修改范圍!
  PL/SQL 過程已成功完成。

步驟8:授權(quán)其他用戶調(diào)用包:
如果是另外一個用戶要使用該包,必須由包的所有者授權(quán),下面授予STUDEN賬戶對該包的使用權(quán):

復(fù)制代碼 代碼如下:

GRANT EXECUTE ON EMP_PK TO STUDENT;

每一個新的會話要為包中的公用變量開辟新的存儲空間,所以需要重新執(zhí)行初始化過程。兩個會話的進程互不影響。
步驟9:其他用戶調(diào)用包。
啟動另外一個SQL*Plus,登錄STUDENT賬戶,執(zhí)行以下過程:

復(fù)制代碼 代碼如下:

SET SERVEROUTPUT ON
  EXECUTE SCOTT.EMP_PK. EMP_PK.INIT(5000,700);

結(jié)果為:

復(fù)制代碼 代碼如下:

提示信息:初始化過程已經(jīng)完成!
  PL/SQL 過程已成功完成。

說明:在初始化中設(shè)置雇員的總?cè)藬?shù)和修改工資的上、下限,初始化后V_EMP_COUNT為14人,插入雇員后V_EMP_COUNT為15人。V_EMP_COUNT為公有變量,所以可以在外部程序中使用DBMS_OUTPUT.PUT_LINE輸出,引用時用EMP_PK.V_EMP_COUNT的形式,說明所屬的包。而私有變量V_MAX_SAL和V_MIN_SAL不能被外部訪問,只能通過內(nèi)部過程來修改。同樣,EXIST_EMP和SHOW_MESSAGE也是私有過程,也只能在過程體內(nèi)被其他模塊引用。
注意:在最后一個步驟中,因為STUDENT模式調(diào)用了SCOTT模式的包,所以包名前要增加模式名SCOTT。不同的會話對包的調(diào)用屬于不同的應(yīng)用,所以需要重新進行初始化。
練習(xí)
1.如果存儲過程的參數(shù)類型為OUT,那么調(diào)用時傳遞的參數(shù)應(yīng)該為:
     A.常量 B.表達式                C.變量 D.都可以
2.下列有關(guān)存儲過程的特點說法錯誤的是:
     A.存儲過程不能將值傳回調(diào)用的主程序
     B.存儲過程是一個命名的模塊
     C.編譯的存儲過程存放在數(shù)據(jù)庫中
     D.一個存儲過程可以調(diào)用另一個存儲過程
3.下列有關(guān)函數(shù)的特點說法錯誤的是:
     A.函數(shù)必須定義返回類型
     B.函數(shù)參數(shù)的類型只能是IN
     C.在函數(shù)體內(nèi)可以多次使用RETURN語句
     D.函數(shù)的調(diào)用應(yīng)使用EXECUTE命令
4.包中不能包含的元素為:
     A.存儲過程 B.存儲函數(shù)
     C.游標(biāo)    D.表
5.下列有關(guān)包的使用說法錯誤的是:
     A.在不同的包內(nèi)模塊可以重名
     B.包的私有過程不能被外部程序調(diào)用
     C.包體中的過程和函數(shù)必須在包頭部分說明
     D.必須先創(chuàng)建包頭,然后創(chuàng)建包體

您可能感興趣的文章:
  • Oracle存儲過程返回游標(biāo)實例詳解
  • oracle 在一個存儲過程中調(diào)用另一個返回游標(biāo)的存儲過程
  • Oracle存儲過程入門學(xué)習(xí)基本語法
  • Oracle中 關(guān)于數(shù)據(jù)庫存儲過程和存儲函數(shù)的使用
  • oracle如何恢復(fù)被覆蓋的存儲過程
  • oracle數(shù)據(jù)庫中查看系統(tǒng)存儲過程的方法
  • oracle 存儲過程和函數(shù)例子
  • Oracle 存儲過程總結(jié) 二、字符串處理相關(guān)函數(shù)
  • Oracle存儲過程和存儲函數(shù)創(chuàng)建方法(詳解)
  • Oracle存儲過程和自定義函數(shù)詳解
  • Oracle學(xué)習(xí)記錄之使用自定義函數(shù)和觸發(fā)器實現(xiàn)主鍵動態(tài)生成
  • oracle 存儲過程、函數(shù)和觸發(fā)器用法實例詳解

標(biāo)簽:六安 葫蘆島 宜春 泰安 孝感 淮南 海北 酒泉

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《oracle 存儲過程詳細介紹(創(chuàng)建,刪除存儲過程,參數(shù)傳遞等)》,本文關(guān)鍵詞  oracle,存儲,過程,詳細,介紹,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《oracle 存儲過程詳細介紹(創(chuàng)建,刪除存儲過程,參數(shù)傳遞等)》相關(guān)的同類信息!
  • 本頁收集關(guān)于oracle 存儲過程詳細介紹(創(chuàng)建,刪除存儲過程,參數(shù)傳遞等)的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    亳州市| 班戈县| 建水县| 江源县| 太仓市| 卢湾区| 锦屏县| 宿迁市| 巫溪县| 凉城县| 会泽县| 上高县| 凤山市| 四川省| 石狮市| 灵寿县| 博兴县| 万盛区| 云和县| 芜湖市| 万宁市| 永登县| 巴中市| 咸丰县| 辉南县| 宽甸| 朝阳区| 墨江| 浪卡子县| 渭南市| 滁州市| 元氏县| 布拖县| 威信县| 龙海市| 玉龙| 望城县| 铜陵市| 许昌市| 咸宁市| 新田县|