Oracle中的包

本文深入讲解Oracle数据库中的包管理概念,包括包规范和包体的创建、使用自定义类型、过程和函数的分类管理,以及如何通过包提高代码的可维护性和安全性。同时,提供了详细的示例代码和调用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

包(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"));
}

更多相关知识请戳我主页!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值