包(package)
在一个大型项目中,可能有很多模块,而每个模块又有自己的过程、函数等。而这些过程、函数默认是放在一起的(如在 PL/SQL 中,过程默认都是放在一起的,即Procedures 中),这些非常不方便查询和维护,甚至会发生误删除的事件。所以通过使用包就可以分类管理过程和函数。
而且在包中还可以自定义自定义类型,从而在过程和函数中可以直接使用自定义变量。Oracle 中包的概念与 JAVA 中包的概念非常类似,只是 JAVA 中的包是为了分类管理类,但是关键字都是 package。
包分两部分,包规范和包体。
包定义(PACKAGE)
包定义(PACKAGE):包定义部分是为应用程序的接口,声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元素,这些元素为包的公有元素。主要是定义包规范,包规范可单独存在。
CREATE [OR REPLACE] PACKAGE package_name
{IS | AS}
[公有数据类型定义]
[公有游标声明]
[公有变量、常量声明]
[公有子程序声明]
END [package_name];
示例:定义一个包规范
Create or replace package com_my_package
Is
---- 定义结构体
v_sum test_emp.sal%type; --定义表类型
type cursor_type is ref cursor; -- 定义游标类型
v_pi constant number(3,2):= 3.14; -- 定义常量 v_PI
---- 定义过程 find_all
procedure find_all(v_pid in number,my_cursor out cursor_type);
---- 定义函数 sum sal
function sum_sal(v_pid number)
return number;
end;
包主体(PACKAGE BODY)
包主体(PACKAGE BODY):包主体则是包定义部分的具体实现,它定义了包定义部分所声明的游标和子程序,在包主体中还可以声明包的私有元素。如果在包主体中的游标或子程序并没有在包头中定义,那么这个游标或子程序是私有的。
--实现包体,名称一致。
create or replace package body com_my_package
is
--实现过程 find all
procedure find_all(v_pid in number,my_cursor out cursor_type)
is
begin
if v_pid=0 then
open my_cursor for select empno,ename from test_emp;
else
open my_cursor for select empno,ename from test_emp where
deptno=v_pid;
end if;
end find_all;
--实现函数 sum_sal
function sum_sal(v_pid number)
return number is
v_count number;
begin
if v_pid=0 then
select sum(sal) into v_count from test_emp;
else
select sum(sal) into v_count from test_emp where deptno=v_pid;
end if;
return v_count;
end sum_sal;
end com_my_package;
执行包 –调用
---语法: 包名.过程名/函数名[(参数)]/常量
---- sql 中调用函数
select com_my_package.sum_sal(0) from dual;
declare
type cursor_type is ref cursor;
my_cursor cursor_type;
type row_type is record(v_id number(10),v_name varchar2(10));
my_rows row_type;
---- plsql 中调用过程
begin
com_my_package.find_all(0,my_cursor);
loop
fetch my_cursor into my_rows;
exit when my_cursor%notfound;
dbms_output.put_line(my_rows.v_id||my_rows.v_name);
end loop;
end;
--- 调用包中的常量
begin
dbms_output.put_line(com_my_pack.v_pi);
end;
JDBC 访包中的过程及函数
//调用时包名.过程/函数名称
String sql = "{call com_my_package.find_all(?,?)}";
conn = DriverManager.getConnection(url, user, password);
CallableStatement stmt = conn.prepareCall(sql);
stmt.setInt(1,10);
//当输出参数为数据库中 PLSQL 特有的类型时,必须用 OracleTypes 中的常数
stmt.registerOutParameter(2, OracleTypes.CURSOR);
stmt.execute();
//将游标类型强转成 ResultSet
ResultSet rs = (ResultSet)stmt.getObject(2);
while(rs.next()){
System.out.println(rs.getInt("empno"));
System.out.println(rs.getString("ename"));
}
更多相关知识请戳我主页!