转自: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;
}
}