轉自:http://www.dezai.cn/blog/article.asp?id=248
Oracle的程式包是由包頭和包體組成(一般也稱為程式包說明和程式包體),是一種將多個程式員模組(函數 預存程序 變數 遊標等)組合起來的一個Function.
1. 與一般的程式模組的區別在於:程式包有兩部分組成,包頭可以將其看作一個對外的介面來使用,而包體則可以看作具體介面業務的具體實現,包體的聲明部分與PL/SQL中的函數或預存程序的聲明 部分差不多.但在包體中的變數、常量、遊標對包使用者而言是不可見的。
2. 程式包的作用:程式包就像物件導向過程的一個具體類的實現,具有結構化、重用性、模組性的特點,同時程式包中所定義的變數及常量可根據商務邏輯的需要定義為不可見或可見度,包將功能的介面與功能的實現相分離,讓代碼的維護更加容易,同時通過在包體中保持資料的安全防止使用者直接對資料進行訪問。
3. 包頭(程式包說明)
包頭是oracle包與應用程式的接品,用於定義包中的公有組件(變數、常量、預存程序、函數、遊標等)。包頭所定義的公用群組件不僅可以在包內使用,也可以在其它預存程序或函數中使用權。
4. 包體(程式包體)
5. 包頭的格式
Create or replace package package_name is| as
[PRAGMA SERIALLY_REUSABLE;]
公有資料類型定義
公有變數聲明
公有常量聲明
公有異常錯誤聲明
公有遊標聲明
公有函式宣告
公有過程聲明
End package_name;
6. 包體的格式
Create or replace package body package_name is|as
[PRAGMA SERIALLY_REUSABLE;]
私人資料類型定義
私人變數聲明
私人常量聲明
私人異常錯誤聲明
私人函式宣告和定義
私用程序聲明和定義
公有遊標定義
公有函數定義
公有流程定義
Begin
執行部分(初始化部分)
End package_name;
7. 包的使用
<1>調用包的公有變數
對公有組件的調用格式: 包名.組件名稱
Eg. Execute my_pkg.v_sqlerrm :=’test
<2>調用包的公有函數
<3>調用包的公有預存程序
<4>使用多個包
<5>包的刪除
刪除包中的預存程序: drop procedure 預存程序名
刪除包中的函數 drop function 過程名
刪除包體 drop package body 包體名
刪除整個包 drop package 包名
<6>查看包的原始碼
<7>包的修改
8 系統內建包的使用
9.使用包的注意點\
<1>建立包之前,必須明確包的使用權使用者及存取權限,必須考慮包體的聲明及包中所需要實現的商務邏輯.
<2>要刪除程式包,必須擁有程式包或擁有 drop any procedure系統許可權
<3>PRAGMA SERIALLY_REUSABLE 決定所建立的包是否可以被連續調用 如果省略,則包的運行狀態會被放在使用者全域區(PGA),如果使用權,則包的運行狀態會被放在系統全域區(SGA)
<4>公用預存程序 公用函數的聲明 要放在其它聲明之後
<5>在資料庫中一個使用者建立的包體和包頭的名稱是唯一的
<6>在建立包頭和包體的時候 ,如果要查看編譯錯誤,可以使用權show errors;查看錯誤
<7>在包頭中的預存程序 函數名稱必須要與包體中實現部分的預存程序、函數的名稱保持一致
10.Net調用Oracle包
調用包內函數:
string oracle_conn = "User ID=user; Password=password; Data Source=server";
using (OracleConnection conn = new oracleConnection(oracle_conn))
{
conn.Open();
oracleCommand com = new oracleCommand("test_net.f_count", conn);//調用包
com.CommandType = CommandType.StoredProcedure;
//輸入參數
oracleParameter p_input = new oracleParameter("str", oracleType.VarChar, 10);
p_input.Direction = System.Data.ParameterDirection.Input;
p_input.Value = "function";
//返回參數
oracleParameter p_output = new oracleParameter("result", oracleType.VarChar, 100);
p_output.Direction = System.Data.ParameterDirection.ReturnValue;
com.Parameters.Add(p_input);
com.Parameters.Add(p_output);
com.ExecuteNonQuery();
conn.Close();
Response.Write(p_output.Value.ToString());
}
調用包內過程:
string oracle_conn = "User ID=user; Password=password; Data Source=server";
using (OracleConnection conn = new oracleConnection(oracle_conn))
{
conn.Open();
oracleCommand com = new oracleCommand("test_net.p_serach", conn);
com.CommandType = CommandType.StoredProcedure;
oracleParameter p_input = new oracleParameter("mycs", oracleType.Cursor);
p_input.Direction = System.Data.ParameterDirection.Output;
com.Parameters.Add(p_input);
oracleDataAdapter da = new oracleDataAdapter(com);
DataSet ds = new DataSet();
da.Fill(ds, "test");
conn.Close();
}
11.Java調用包過程
package JDBC;
/**
* 作者:may
* 時間:15:09:23
*/
import java.sql.*;
import oracle.jdbc.driver.*;
public class proctest {
public static void main(String[] args) {
proctest pc = new proctest();
pc.ShowContent();
}
String sDBDriver="oracle.jdbc.driver.OracleDriver";
String sConnStr="jdbc:oracle:thin:@10.3.8.48:1521:ORADB";
Connection connect=null;
ResultSet rs = null;
public proctest(){
try{
Class.forName(sDBDriver);
}
catch(ClassNotFoundException e){
System.err.println(e.getMessage());
}
}
public ResultSet ShowContent()
{
try{
connect = DriverManager.getConnection(sConnStr,"SHUIBJ","SHUIBJ");
CallableStatement stmt = connect.prepareCall("{call PKG_TEST.GET(?,?,?)}");
stmt.setString(1,"all"); //輸入參數
stmt.registerOutParameter(2,Types.CHAR); //輸出參數為普通參數
stmt.registerOutParameter(3,OracleTypes.CURSOR); //輸出參數為結果集參數
stmt.executeQuery();
rs = ((OracleCallableStatement) stmt).getCursor(3); //得到輸出結果集參數
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
String str = stmt.getString(2);
System.out.println("第二個參數為:"+str);
System.out.println("結果集列數"+numberOfColumns);
//列出結果集中的記錄
ResultSetMetaData md = rs.getMetaData();
int nColumns = md.getColumnCount();
for (int i=1;i<=nColumns;i++){
System.out.print(md.getColumnName(i)+((i==nColumns)?"\n":"\t"));
if(i==2) System.out.print("\t");
}
while (rs.next()){
for(int i=1;i<=nColumns;i++){
System.out.print(rs.getString(i)+((i==nColumns)?"\n":"\t"));
}
}
}
catch(SQLException ex){
System.err.println(ex.getMessage()+"連資料庫有問題!");
}
return rs;
}
}