1. 程式人生 > >Oracle的Package的作用及用法

Oracle的Package的作用及用法

簡化應用設計、提高應用效能、實現資訊隱藏、子程式過載。

1、Oracle的Package除 了把儲存過程放到一堆兒以外還有沒有其他的作用(好處)?

你不覺得把儲存過程分門別類是很重要的麼,而且不同的package的儲存過程可以重 名。
用package不僅能把儲存過程分門別類,而且在package裡可以定義公共的變數/型別,既方便了程式設計,又減少了伺服器的編譯開銷。

2、如何把現有的儲存過程加入到Package中?
copy and pasty,不過呼叫的時候要帶包名了。

3、除了使用SQL Plus,還有沒有什麼工具做Package?
也有方便的第三方工具了,不過得自己找了。
用第三方工具吧,比如sql navigator。www.quest.com

4、使用SQL Plus編譯Package,是否每次都是編譯Package中所有的儲存過程?




包也是一種命名pl/sql塊,和儲存過程、函式一下,都是在資料庫啟動的時候就載入記憶體的。開銷的大小很難判斷,因為你不用包,但是要完成包的功能的話,還是要用PL/SQL來完成的,伺服器一樣有開銷。相對來說,用包少了SQL的語法分析、解釋過程,開銷還少一點。

“過程一般都不超過20行”那我倒很少遇到。用不用子過程關鍵要看是不是能定義可重用的子過程,用子過程效率不會低。

包的作用:包可以將任何出現在塊宣告的語句(過程,函式,遊標,遊標,型別,變數)放於包中,相當於一個容器.將宣告語句放入包中的好處是:使用者可以從其他PL/SQL塊中對其進行引用,因此包為PL/SQL提供了全程變數.

包分為兩部分:包頭和包體.

如何建立包?

1)包頭:

語法格式:

CREATE OR REPLACE PACKAGEpackage_name /*包頭名稱*/

IS|AS pl/sql_package_spec                     /*定義過程,函式以及返回型別,變數,常量及資料型別定義*/

定義包頭應當遵循以下原則:

1)包元素位置可以任意安排.然而在宣告部分,物件必須在引用前進行宣告.

2)包頭可以不對任何型別的元素進行說明.例如,包頭可以只帶過程和函式說明語句,而不宣告任何異常和型別.

3)對過程和函式的任何宣告都必須只對子程式和其引數進行描述,不能有任何程式碼的說明,程式碼的實現只能在包體中出現.它不同於塊宣告,

在塊宣告中,過程和函式的程式碼可同時出現在宣告部分.

2.包體:

語法格式:

CREATE OR REPLACE PACKAGE BODY package_name/*包名必須與包頭的包名一致*/

IS | AS pl/sql_package_body                    /*遊標,函式,過程的具體定義*/

包體是與包頭相互獨立的,包體只能在包頭完成編譯後才能進行編譯.包體中帶有包頭中描述的子程式的具體實現的程式碼段.除此之外,包體還可以包括具有包體人全句屬性的附加宣告部分,但這些附加宣告對於包頭是不見的.

EG:定義一個包頭

CREATE OR REPLACE PACKAGE select_table

IS

TYPE tab_02 IS RECORD

(

itnum_1 varchar2(1),

itnum_2 varchar2(1)

);

TYPE tab_03 IS RECORD

(

itnum_1 varchar2(1),

itnum_2 varchar2(1),

itnum_3 varchar2(1)

);

TYPE tab_04 IS RECORD

(

itnum_1 varchar2(1),

itnum_2 varchar2(1),

itnum_3 varchar2(1),

itnum_4 varchar2(1)

);

TYPE tab_05 IS RECORD

(

itnum_1 varchar2(1),

itnum_2 varchar2(1),

itnum_3 varchar2(1),

itnum_4 varchar2(1),

itnum_5 varchar2(1)

);

TYPE tab_06 IS RECORD

(

itnum_1 varchar2(1),

itnum_2 varchar2(1),

itnum_3 varchar2(1),

itnum_4 varchar2(1),

itnum_5 varchar2(1),

itnum_6 varchar2(1)

);

TYPE cur_02 IS REF CURSOR RETURNtab_02;

TYPE cur_03 IS REF CURSOR RETURNtab_03;

TYPE cur_04 IS REF CURSOR RETURNtab_04;

TYPE cur_05 IS REF CURSOR RETURNtab_05;

TYPE cur_06 IS REF CURSOR RETURNtab_06;

END select_tab;

EG:

CREATE OR REPLACE PACKAGE test_package

IS

FUNCTION average

(cnum IN char)

RETURN NUMBER;

PRODURE student_grade

(CUR OUT select_table.cur_04);--CUR的資料型別是select_table包中cur_o4

END test_package;

包體:

CREATE OR REPLACE PACKAGE BODY test_package

IS

/*函式實現開始*/

FUNCTION average                        

(cnum IN char)

RETURN NUMBER;

AS

avger NUMBER;

BEGIN

SELECT AVG(CJ) INTO avger FROM XS_KC WHERE KCH=cnum GROUP BYKCH;

RETURN(avger);

END average;

/*函式實現結束*/

/*過程實現開始*/

PRODURE student_grade

(CUR OUT select_table.cur_04);

AS

OPEN CUR FOR

SELECT XS.XH ,XS.XM,KC.KCM,XS_KC.CJ

FROM XS ,XS_KC,KC

WHERE XS.XH =XS_KC.XH AND XS_KC.KCH=KC.KCH;

END student_grade;

/*過程實現結束*/

END test_package;

過載:包中的函式和過程可以過載

以下條件不能過載:

1.如果兩個子程式的引數僅在名稱和型別上不同,這兩個程式不能過載.

PROCEDURE overloadME(p_theparameterIN number);

PROCEDURE overloadME(p_theparameterOUT number);

IN ,OUT為引數型別,number為資料型別.兩個過程僅在型別上不同時不能過載.

2.不能根據兩個函式的返回型別對其過載

:

FUNCTION overloadMeETooRETURN DATE;

FUNCTION overloadMeETooRETURN NUMER;

3.過載子程式的引數的類族必須不同,例如,由於CHARVARCHAR2屬性同一類族,所以不能過載 .

PROCEDURE overloadME(p_theparameterIN char);

PROCEDURE overloadME(p_theparameterIN varchar2);

4.打包子程式也可以過載

5.包的初始化.

當第一次呼叫打包子程式時,該包將進行初始化.也就是說,將該包從硬碟中讀入到記憶體,並啟用呼叫的子程式的編譯程式碼.這時,系統為該包中定義的所有變數分配記憶體單元.每個會話都有打其開啟包變數的副本,以確保執行同一個包子程式的兩個會話使用不同的記憶體單元.

在大多數情況下,初始化程式碼要在包第一次初始化時執行.為了實現這一功能,可以在包體中的所有物件之後加入一個初始化程式碼 .

語法格式:

CREATE OR REPLACE PACKAGE BODYpackage_name

IS|AS

............

BEGIN

Initialization_code;--要執行的初始化程式碼

END ;

ORACLE 內建包

1.DBMS_ALERT:用於資料庫報警,允許會話間通訊

2.DBMS_JOB:用於任務排程服務

3.DBMS_LOB:用於處理大物件操作

4.DBMS_PIPE:用於資料庫管道,允許會話間通訊

5.DBMS_SQL:用於執行動態SQL

6.UTL_FILE:用於檔案的輸入輸出

除了UTL_FILE包儲存在伺服器和客戶端外,其他的包均儲存在伺服器中