首先,需要重新整理一下相關概念,oracle資料庫中函數的作用,是只能被別人調用,預存程序可以單獨執行,並且可以調用預存程序,而包的作用包可以將任何出現在塊聲明的語句 ( 過程 , 函數 , 遊標 , 遊標 , 類型 , 變數 ) 放於包中 , 相當於一個容器 . 將聲明語句放入包中的好處是 : 使用者可以從其他 PL/SQL 塊中對其進行引用 , 因此包為 PL/SQL 提供了全域變數,包分為包頭和包體,包頭先編譯通過後才能編譯包體。
包頭的建立:
1) 包頭 :
文法格式 :
CREATE OR REPLACE PACKAGE package_name /* 包頭名稱 */
IS|AS
pl/sql_package_spec /* 定義過程 , 函數以及傳回型別 , 變數 , 常量及資料類型定義 */
定義包頭應當遵循以下原則 :
1) 包元素位置可以任意安排 . 然而在聲明部分 , 對象必須在引用前進行聲明 .
2) 包頭可以不對任何類型的元素進行說明 . 例如 , 包頭可以只帶過程和函數說明語句 , 而不聲明任何異常和類型 .
3) 對過程和函數的任何聲明都必須只對子程式和其參數進行描述 , 不能有任何代碼的說明 , 代碼的實現只能在包體中出現 . 它不同於塊聲明 , 在塊聲明中 , 過程和函數的代碼可同時出現在聲明部分 .
2. 包體 :
文法格式 :
CREATE OR REPLACE PACKAGE BODY package_name/* 包名必須與包頭的包名一致 */
IS | AS
pl/sql_package_body /* 遊標 , 函數 , 過程的具體定義 */
包體是與包頭相互獨立的 , 包體只能在包頭完成編譯後才能進行編譯 . 包體中帶有包頭中描述的子程式的具體實現的程式碼片段 . 除此之外 , 包體還可以包括具有包體人全句屬性的附加聲明部分 , 但這些附加聲明對於包頭是不見的 .
Demo:
****************
*包
****************
create or replace package mypack
as
type mytype is ref cursor return emp%rowtype; --聲明REF遊標
function myemp(dno number) return mytype;
end;
****************
*body
****************
create or replace package body mypack
as
function myemp(dno number) return mytype
as
eee mytype;--聲明Ref 遊標類型變數
begin
open eee for select * from emp where deptno=dno;
return eee;
end myemp;
end mypack;
分析:
在包頭中出現了type mytype is ref cursor return emp%rowtype;
裡面有一個REF CURSOR的概念, REF遊標就是動態關連接果集的臨時對象。即在啟動並執行時候動態決定執行查詢,他的主要作用就是實現在程式間傳遞結果集的功能
①聲明REF遊標
⑴強型別REF遊標:指定retrun type,REF 遊標變數的類型必須和return type一致。
文法:Type REF遊標名 IS ref cursor Return 結果集返回記錄類型;
⑵弱類型REF遊標:不指定return type,能和任何類型的CURSOR變數匹配,用於擷取任何結果集。
文法:Type REF遊標名 IS ref cursor ;
②聲明Ref 遊標類型變數;
文法:變數名 已聲明Ref 遊標類型;
③開啟REF遊標,關連接果集 ;
文法:Open Ref 遊標類型變數 For 查詢語句返回結果集;
④擷取記錄,操作記錄;
文法:fetch REF遊標名 InTo 臨時記錄類型變數或屬性類型變數列表;
⑤關閉遊標,完全釋放資源;
文法:Close REF遊標名;
附上測試代碼:
create or replace package mypack
as
type mytype is ref cursor return emp%rowtype;
function myemp(dno number) return mytype;
end;
create or replace package body mypack
as
function myemp(dno number) return mytype
as
eee mytype;
begin
open eee for select * from emp where deptno=dno;
return eee;
end myemp;
end mypack;
drop table emp;
create table emp
(
DEPTNO number,
COMM number,
SAL number
);
Delete from emp Where deptno=10;
Delete from emp Where deptno=11;
Insert Into emp (deptno,comm,sal) Values (10,1,2);
Insert Into emp (deptno,comm,sal) Values (11,2,3);
Commit;