oracle包详解(二)【weber出品】
一、重载子程序
PL/SQL中的重载功能:
1. 能够使用户创建两个或多个同名的子程序
2. 要求子程序的形式参数的数量,顺序或者数据类型不一样
3. 能够使用户使用不同的数据灵活的调用子程序
4. 对已经存在的代码的功能的扩展
注意: 重载可以对本地子程序,包,包中的子程序,方法进行重载,不能对标准的子程序进行重载
示例:先创建表和序列
conn scott/tiger drop table d purge; create table d as select * from dept where = create sequence s1
increment by
start with
maxvalue
cycle
nocache;
创建包头:
create or replace package dept_pkg is
procedure add_dept(v_deptno d.deptno%type,
v_dname d.dname%type,
v_loc d.loc%type);
procedure add_dept(v_dname d.dname%type, v_loc d.loc%type);
end;
创建包体:
create or replace package body dept_pkg is
procedure add_dept(v_deptno d.deptno%type,
v_dname d.dname%type,
v_loc d.loc%type) is
begin
insert into d values (v_deptno, v_dname, v_loc);
commit;
end; procedure add_dept(v_dname d.dname%type, v_loc d.loc%type) is
begin
insert into d values (s1.nextval, v_dname, v_loc);
commit;
end;
end;
调用包:
SQL> execute dept_pkg.add_dept(,'dname','chengdu');
PL/SQL procedure successfully completed SQL> select * from d;
DEPTNO DNAME LOC
------ -------------- -------------
dname chengdu SQL> exec dept_pkg.add_dept('RESEARCH','DALLAS'); PL/SQL 过程已成功完成。 SQL> execute dept_pkg.add_dept('dname2','chengdu2');
PL/SQL procedure successfully completed SQL> select * from d;
DEPTNO DNAME LOC
------ -------------- -------------
dname chengdu
dname2 chengdu2
重载和标准包:
标准包是oracle内置的包
大部分内置的包被重载,比如函数:TO_CHAR
如果在本地子程序使用了与标准包子程序相同的名,本地子程序必须使用包名
二、使用前置的声明
块结构语言(比如PL/SQL) 在引用之前必须先声明
创建新表:
conn scott/tiger drop table e purge; create table e as select empno,ename,deptno from emp where =
创建包头:
create or replace package admin_salary is
procedure add_emp(eno number, name varchar2, dno number);
end;
创建包体:
create or replace package body admin_salary is
function check_empno(eno number) return boolean;
procedure add_emp(eno number, name varchar2, dno number) is
begin
if check_empno(eno) then
insert into e values (eno, name, dno);
commit;
else
dbms_output.put_line('invalidate data');
end if;
end;
function check_empno(eno number) return boolean is
begin
if eno between and then
return true;
else
return false;
end if;
end;
end;
调用包:
SQL> set serveroutput on SQL> exec admin_salary.add_emp(,'ZSAN',); invalidate data PL/SQL 过程已成功完成。 SQL> exec admin_salary.add_emp(,'ZSAN',); PL/SQL 过程已成功完成。 SQL> select * from e; EMPNO ENAME DEPTNO
----- ------ ------
ZSAN
三、包中的初始化块
这种块在包体内只执行一次,用于初始化公共和私有变量
创建包头:
create or replace package emp_package is
minsal number();
maxsal number();
procedure add_emp(eno number, name varchar2, salary number);
procedure upd_sal(eno number, salary number);
procedure upd_sal(name varchar2, salary number);
end;
创建包体:
create or replace package body emp_package is
procedure add_emp(eno number, name varchar2, salary number) is
begin
if salary between minsal and maxsal then
insert into emp (empno, ename, sal) values (eno, name, salary);
commit;
else
raise_application_error(-, '工资不在范围之内');
end if;
exception
when dup_val_on_index then
raise_application_error(-, '该雇员已经存在');
end; procedure upd_sal(eno number, salary number) is
begin
if salary between minsal and maxsal then
update emp set sal = salary where empno = eno;
if sql%notfound then
raise_application_error(-, '不存在该雇员号');
end if;
else
raise_application_error(-, '工资不在范围之内');
end if;
end; procedure upd_sal(name varchar2, salary number) is
begin
if salary between minsal and maxsal then
update emp set sal = salary where ename = name;
if sql%notfound then
raise_application_error(-, '不存在该雇员');
end if;
else
raise_application_error(-, '工资不在范围之内');
end if;
end;
begin
select min(sal), max(sal) into minsal, maxsal from emp; ----初始化块
end;
执行过程:
SQL> exec emp_package.add_emp(,'ZSAN',); BEGIN emp_package.add_emp(,'ZSAN',); END; *
第 行出现错误:
ORA-: 工资不在范围之内
ORA-: 在 "SCOTT.EMP_PACKAGE", line
ORA-: 在 line SQL> exec emp_package.add_emp(,'ZSAN',); PL/SQL 过程已成功完成。 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
SMITH CLERK -12月-
ALLEN SALESMAN -2月 -
WARD SALESMAN -2月 -
JONES MANAGER -4月 -
MARTIN SALESMAN -9月 -
BLAKE MANAGER -5月 -
CLARK MANAGER -6月 -
SCOTT ANALYST -4月 -
KING PRESIDENT -11月-
TURNER SALESMAN -9月 -
ADAMS CLERK -5月 -
JAMES CLERK -12月-
FORD ANALYST -12月-
MILLER CLERK -1月 -
ZSAN 已选择15行。 SQL> exec emp_package.upd_sal(,);
BEGIN emp_package.upd_sal(,); END; *
第 行出现错误:
ORA-: 工资不在范围之内
ORA-: 在 "SCOTT.EMP_PACKAGE", line
ORA-: 在 line SQL> exec emp_package.upd_sal(,); PL/SQL 过程已成功完成。 SQL> select * from emp where empno=; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
SCOTT ANALYST -4月 - SQL> exec emp_package.upd_sal('SCOTT',); PL/SQL 过程已成功完成。 SQL> select * from emp where empno=; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
SCOTT ANALYST -4月 -
四、在SQL中使用包函数和限制
包函数可以用于SQL语句中:
CREATE OR REPLACE PACKAGE taxes_pkg IS
FUNCTION tax (value IN NUMBER) RETURN NUMBER;
END taxes_pkg;
/
CREATE OR REPLACE PACKAGE BODY taxes_pkg IS
FUNCTION tax (value IN NUMBER) RETURN NUMBER IS
rate NUMBER := 0.08;
BEGIN
RETURN (value * rate);
END tax;
END taxes_pkg;
/ SELECT taxes_pkg.tax(salary), salary, last_name--引用包中的函数,必须加包名
FROM employees;
五、在包中使用PL/SQL记录表:
创建包头和包体:
create or replace package emp_pkg is
type emp_table_type is table of employees%rowtype index by binary_integer;
procedure get_emp(emps out emp_table_type);
end; create or replace package body emp_pkg is
procedure get_emp(emps out emp_table_type) is
i binary_integer;
begin
for emp_record in (select * from employees) loop
emps(i) := emp_record;
i := i + ;
end loop;
end;
end;
SQL中调用:
declare
employees emp_pkg.emp_table_type;
begin
emp_pkg.get_emp(employees);
for i in employees.first..employees.last loop
dbms_output.put_line('员工的名:' || employees(i).last_name);
end loop;
end;
六、PL/SQL封装
PL/SQL wrapper 是一个单独的工具,通过将PL/SQL源代码转换为其他代码,用来隐藏应用程序内部组件
Wrapping 有以下功能:
1. 平台独立性
2. 动态加载
3. 动态绑定
4. 依赖性检测
当调用时,正常导入和导出
运行Wrapper:
语法:
WRAP INAME=input_file_name [ONAME=output_file_name]
INAME参数是必须的
输入文件默认的扩展名.sql,
ONAME 参数是可选的
输出文件默认的扩展名.plb,
示例:
cd /u01
vi pkg.sql写入如下内容:
create or replace package emp_pkg is
type emp_table_type is table of employees%rowtype index by binary_integer;
procedure get_emp(emps out emp_table_type);
end;
/
create or replace package body emp_pkg is
procedure get_emp(emps out emp_table_type) is
i binary_integer;
begin
for emp_record in (select * from employees) loop
emps(i) := emp_record;
i := i + ;
end loop;
end;
end;
/
进行加密:
wrap iname=/u01/pkg.sql oname=/u01/pkg.plb sqlplus hr/hr @/u01/pkg.plb select text from user_source where name='EMP_PKG' and type='PACKAGE'; select text from user_source where name='EMP_PKG' and type='PACKAGE BODY';
包头包体头加密
封装的规则:
可以检测语法错误,不能检测语义错误
输出文件不能被编辑,只能对最初的源代码进行维护,然后再次封装
oracle包详解(二)【weber出品】的更多相关文章
- ORACLE函数详解【weber出品】
一.什么是函数 一个函数: 1. 是命名的PL/SQL块,必须返回一个值 2. 可以存储到数据库中重复执行 3. 可以作为表达式的一部分或者提供一个参数值 二.创建函数的语法 必须至少有一个返回值,创 ...
- Oracle中dbms_random包详解
Oracle之DBMS_RANDOM包详解参考自:https://www.cnblogs.com/ivictor/p/4476031.html https://www.cnblogs.com/shen ...
- 常见 jar包详解
常见 jar包详解 jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周期 ...
- oracle rowid 详解
oracle rowid详解 今天是2013-09-15,存储在数据库中的每一行数据都有一个地址,oracle使用rowid数据类型在存储地址.rowid有如下类别: 1)physical rowid ...
- JAVA通过JDBC连接Oracle数据库详解【转载】
JAVA通过JDBC连接Oracle数据库详解 (2011-03-15 00:10:03) 转载▼http://blog.sina.com.cn/s/blog_61da86dd0100q27w.htm ...
- 问题:Oracle出发器;结果:1、Oracle触发器详解,2、Oracle触发器示例
ORACLE触发器详解 本篇主要内容如下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 触发器触发次序 8.2.2 创 ...
- 在RedHat 5下安装Oracle 10g详解(转)
在RedHat 5下安装Oracle 10g详解(转) Posted on 2012-09-14 13:26 疯狂 阅读(5075) 评论(0) 编辑 收藏 所属分类: database .uni ...
- Oracle 同义词详解(synonym)
Oracle 同义词详解(synonym) 一.Oracle同义词概念 Oracle 数据库中提供了同义词管理的功能.同义词是数据库方案对象的一个别名,经常用于简化对象访问和提高对象访问的安全性.在使 ...
- Oracle数据字典详解
学习笔记:oracle数据字典详解 --- 本文为TTT学习笔记,首先介绍数据字典及查看方法,然后分类总结各类数据字典的表和视图.然后列出一些附例. 数据字典系统表,保存在system表空间中. ...
随机推荐
- 监听键盘 防止输入时覆盖掉textfiled
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardwasChange:) name:U ...
- pch文件出现no such file or directory错误
一般出现这种情况是由于项目直接拷贝到其他电脑上运行... clang: error: no such file or directory: '/demo2/控件代码/13/Recorder/Recor ...
- access 2007 vba 开发中学到的知识(一)
使用ado连接本身的数据库,需要先创建一个 adodb.connection的连接对象 Set cn = CreateObject("ADODB.Connection") 数据库的 ...
- HTML写的第一个邮箱登陆界面
自己动手去写才会有收获,宁可模仿也不要全部复制粘贴 不说了,直接上代码.CSS有注释,适合新手. <!doctype html> <html> <head> < ...
- Matlab 取子矩阵
MATLAB如何提取矩阵的子块 在matlab中如何提取一个矩阵的部分元素 1.提取大矩阵的一列.一行元素: 一列元素: A(:,j)表示提取A矩阵的第j列全部元素 一行元素: A(i,:)表示提 ...
- C#使用log4net
C#很多异步机制使程序无法使用断点调试,这时候我们就需要使用日志输出.使用log4net一定要先引用net4log这个dll,不然无法使用. 作者很懒,直接上代码吧. using System; us ...
- php 之 分页查询的使用方法及其类的封装
一.分页的使用: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- javascript事件详细说明
javascript事件列表解说javascript事件列表解说事件 浏览器支持 解说一般事件 onclick IE3.N2 鼠标点击时触发此事件ondblclick IE4.N4 鼠标双击时触发此事 ...
- Activiti工作流学习-----基于5.19.0版本(5)
五.与Spring集成 实际项目中一般都有Spring的身影,与Spring集成使得Activiti的实用性得到提高.activiti和Spring整合需要activiti-spring的jar在类路 ...
- hdu 2016
Problem Description 输入n(n<100)个数,找出其中最小的数,将它与最前面的数交换后输出这些数. Input 输入数据有多组,每组占一行,每行的开始是一个整数n,表示这 ...