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表空间中. ...
随机推荐
- C#生成Code39(extend)条形码【非条形码字体】
Code39是条形码的一种.由于编制简单.能够对任意长度的数据进行编码.支持设备广泛等特性而被广泛采用. 能够对任意长度的数据进行编码.其局限在于印刷品的长度和条码阅读器的识别范围. 支持设备广泛.目 ...
- GDI相关基础知识
原文链接:http://blog.csdn.net/poem_qianmo/article/details/7333886 GDI(Graphics Device Interface) 图形设备接口, ...
- swt
http://blog.sina.com.cn/s/blog_557ebb4c0101mgtc.html http://blog.csdn.net/kagoy/article/details/1746 ...
- 腾讯CMEM的PHP扩展(转载)
题外话最近公司在做相关的业务,由于Memcached协议缺少返回码,为了保证业务数据的安全性,不得已只好自己写个扩展来实现需求. 基于memcache扩展的2.2.6的稳定版开发而来.代码已经开源,有 ...
- dede调用指定的多个栏目导航
{dede:channelartlist row=' typeid='1,2这里输入多个指定的栏目ID' } <li><a href='{dede:field name='typeu ...
- Python新手学习基础之函数-return语句与函数调用
return语句 return语句的写法是: return 表达式 return语句用于退出函数,选择性地向调用方返回一个表达式.return在不带参数的情况下,默认返回None. None是一个特殊 ...
- python construct文档
The Basics Fields Fields are the most fundamental unit of construction: they parse (read data from t ...
- linux内核学习之四:进程切换简述
在讲述专业知识前,先讲讲我学习linux内核使用的入门书籍:<深入理解linux内核>第三版(英文原版叫<Understanding the Linux Kernel>),不过 ...
- Linux_access the file or directory which start with "-"
cd -- filename/dirName [ccmobil@vm-a65a-fc19 wstemp]$ cd -/ -bash: cd: -: invalid option cd: usage: ...
- 怎样在Word中插入代码并保持代码原始样式不变
怎样在Word中插入代码并保持样式不变 我们有时候需要在word中添加一段我们写的代码,但是把代码粘贴到word文档中之后就发现所有的代码的样子都变了,我们可以采用下边的方法来实现保持代码原来的样式和 ...