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表空间中. ...
随机推荐
- ORACLE 物化视图
最近几天,我负责的P项目环境中提供给W系统的一个视图,由于查询逻辑复杂,数据量比较大,导致每次查询视图的时候,查询速度慢,效率低下,遭到了w系统人员的投诉.想了想,还是改成物化视图吧,用了物化视图,腰 ...
- uva 10994 - Simple Addition
//组合数学 //计算sum{i从右往左数的第一个非0数字,p<=i<=q}. #include <cstdio> typedef long long ll; ll sum(l ...
- 微信支付:redirect_uri参数错误 的解决办法
redirect_url参数错误: 报这个错误,说明你的公众号后台授权设置有问题(一般有两处) 一:检查授权目录 答:支付授权目录是网站发起请求的页面所在目录,并且必须是能通过url地址访问的(与真实 ...
- Zepto源码笔记(三)
ps:本文中"组装成成数组"指的是若元素个数大于1则返回数组,若元素只有1个则返回元素本身 以下函数是$.fn该对象的方法 ready(callback) 通过readyRE正则表 ...
- xcode5.1上真机调试报告No architectures to compile for...的解决办法
由于手头上只有一台IPAD一代,近期升级到IOS5.0了(人家apple只让升级到此为止)而开发环境Xcode版本是5.1,默认情况下XCode编译出来的代码最低能跑在IOS6.0下, 于是GOOGL ...
- C程序设计语言练习题1-9
练习1-9 编写一个将输入复制到输出的程序,并将其中连续的多个空格用一个空格代替. 代码如下: #include <stdio.h> // 包含标准库的信息. int main() // ...
- GO实例3 Slice append打印
package main import "fmt" func main(){ ]int slice:=array[:] slice[]='a' slice[]='b' s1:=ap ...
- 字符串时间日期转为Date格式和long格式
public static Long compare_date(String DATE1, String DATE2) { DateFormat df = new SimpleDateFormat(& ...
- Swift--访问级别-备
访问级别: Swift提供了3种不同访问级别,对应的访问修饰符为:public.internal和private.这些访问修饰符可以修饰类.结构体.枚举等面向对象的类型,还可以修饰变量.常量.下标.元 ...
- 编写Swift代码的其他工具
Swift程序不能在Windows其他平台编译和运行,有人提供了一个网站swiftstub.com,左栏是代码编辑窗口,右栏是运行结果窗口.可以在任何平台下编译和运行Swift程序.