oracle包详解(二)【weber出品】

一、重载子程序

PL/SQL中的重载功能:

1. 能够使用户创建两个或多个同名的子程序

2. 要求子程序的形式参数的数量,顺序或者数据类型不一样

3. 能够使用户使用不同的数据灵活的调用子程序

4. 对已经存在的代码的功能的扩展

注意: 重载可以对本地子程序,包,包中的子程序,方法进行重载,不能对标准的子程序进行重载

示例:先创建表和序列

conn scott/tiger

drop table d purge;

create table d as select * from dept where 1=2

create sequence s1
increment by 10
start with 10
maxvalue 100
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(10,‘dname‘,‘chengdu‘);
PL/SQL procedure successfully completed

SQL> select * from d;
DEPTNO DNAME          LOC
------ -------------- -------------
    10 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
------ -------------- -------------
    10 dname          chengdu
    10 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 1=2

创建包头:

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 10 and 50 then
      return true;
    else
      return false;
    end if;
  end;
end;

调用包:

SQL> set serveroutput on

SQL> exec admin_salary.add_emp(5,‘ZSAN‘,10);

invalidate data

PL/SQL 过程已成功完成。

SQL> exec admin_salary.add_emp(20,‘ZSAN‘,10);

PL/SQL 过程已成功完成。

SQL> select * from e;

EMPNO ENAME  DEPTNO
----- ------ ------
   20 ZSAN       10

三、包中的初始化块

这种块在包体内只执行一次,用于初始化公共和私有变量

创建包头:

create or replace package emp_package is
  minsal number(6);
  maxsal number(6);
  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(-20001, ‘工资不在范围之内‘);
    end if;
  exception
    when dup_val_on_index then
      raise_application_error(-20002, ‘该雇员已经存在‘);
  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(-20003, ‘不存在该雇员号‘);
      end if;
    else
      raise_application_error(-20001, ‘工资不在范围之内‘);
    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(-20003, ‘不存在该雇员‘);
      end if;
    else
      raise_application_error(-20001, ‘工资不在范围之内‘);
    end if;
  end;
begin
  select min(sal), max(sal) into minsal, maxsal from emp;  ----初始化块
end;

执行过程:

SQL> exec emp_package.add_emp(7777,‘ZSAN‘,80000);

BEGIN emp_package.add_emp(7777,‘ZSAN‘,80000); END;

*
第 1 行出现错误:
ORA-20001: 工资不在范围之内
ORA-06512: 在 "SCOTT.EMP_PACKAGE", line 8
ORA-06512: 在 line 1

SQL> exec emp_package.add_emp(7777,‘ZSAN‘,800);

PL/SQL 过程已成功完成。

SQL> select * from emp;

EMPNO ENAME  JOB         MGR HIREDATE         SAL       COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
 7369 SMITH  CLERK      7902 17-12月-80       800                20
 7499 ALLEN  SALESMAN   7698 20-2月 -81      1600        300     30
 7521 WARD   SALESMAN   7698 22-2月 -81      1250        500     30
 7566 JONES  MANAGER    7839 02-4月 -81      2975                20
 7654 MARTIN SALESMAN   7698 28-9月 -81      1250       1400     30
 7698 BLAKE  MANAGER    7839 01-5月 -81      2850                30
 7782 CLARK  MANAGER    7839 09-6月 -81      2450                10
 7788 SCOTT  ANALYST    7566 19-4月 -87      3000                20
 7839 KING   PRESIDENT       17-11月-81      5000                10
 7844 TURNER SALESMAN   7698 08-9月 -81      1500          0     30
 7876 ADAMS  CLERK      7788 23-5月 -87      1100                20
 7900 JAMES  CLERK      7698 03-12月-81       950                30
 7902 FORD   ANALYST    7566 03-12月-81      3000                20
 7934 MILLER CLERK      7782 23-1月 -82      1300                10
 7777 ZSAN                                    800

已选择15行。

SQL> exec emp_package.upd_sal(7788,80000);
BEGIN emp_package.upd_sal(7788,80000); END;

*
第 1 行出现错误:
ORA-20001: 工资不在范围之内
ORA-06512: 在 "SCOTT.EMP_PACKAGE", line 23
ORA-06512: 在 line 1

SQL> exec emp_package.upd_sal(7788,4000);

PL/SQL 过程已成功完成。

SQL> select * from emp where empno=7788;

EMPNO ENAME  JOB         MGR HIREDATE         SAL       COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
 7788 SCOTT  ANALYST    7566 19-4月 -87      4000                20

SQL> exec emp_package.upd_sal(‘SCOTT‘,3000);

PL/SQL 过程已成功完成。

SQL> select * from emp where empno=7788;

EMPNO ENAME  JOB         MGR HIREDATE         SAL       COMM DEPTNO
----- ------ --------- ----- -------------- ----- ---------- ------
 7788 SCOTT  ANALYST    7566 19-4月 -87      3000                20

四、在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 + 1;
    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 + 1;
    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‘;

包头包体头加密

封装的规则:

可以检测语法错误,不能检测语义错误

输出文件不能被编辑,只能对最初的源代码进行维护,然后再次封装

时间: 2024-07-29 04:09:56

oracle包详解(二)【weber出品】的相关文章

ORACLE函数详解【weber出品】

一.什么是函数 一个函数: 1. 是命名的PL/SQL块,必须返回一个值 2. 可以存储到数据库中重复执行 3. 可以作为表达式的一部分或者提供一个参数值 二.创建函数的语法 必须至少有一个返回值,创建模板: CREATE [OR REPLACE] FUNCTION function_name [(parameter1 [mode1] datatype1, ...)] RETURN datatype IS|AS [local_variable_declarations; …] BEGIN --

ORACLE之UTL_FILE包详解

1 Utl_File包简介Oracle的UTL_FILE包用来实现对磁盘文件的I/O操作.(1)Oracle10g之前的版本需要指定utl_file包可以操作的目录.      方法:        1.alter system set utl_file_dir='e:/utl' scope=spfile;        2.在init.ora文件中,配置如下:UTL_FILE=E:/utl或者UTL_FILE_DIR=E:/utl;(2)Oracle10g之后的版本,只需要先创建一个路径即可.

JAVA通过JDBC连接Oracle数据库详解【转载】

JAVA通过JDBC连接Oracle数据库详解 (2011-03-15 00:10:03) 转载▼http://blog.sina.com.cn/s/blog_61da86dd0100q27w.html Java连接Oracle步骤: 1.注册加载驱动 驱动名:DRIVER="oracle.jdbc.driver.OracleDriver"; Class.forName("驱动类名"); 2.获得连接 数据库地址: URL="jdbc:oracle:thi

问题: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 创建DML触发器 8.2.3 创建替代(INSTEAD OF)触发器 8.2.3 创建系统事件触发器 8.2.4 系统触发器事件属性 8.2.5 使用触发器谓词 8.2.6 重新编译触发器 8.3 删除和使能触发器 8.4 触发器和数据字典 8.5   数据库触发器的应用举例 触发器是许多关系数据库系

oracle权限详解

一.权限分类:系统权限:系统规定用户使用数据库的权限.(系统权限是对用户而言). 实体权限:某种权限用户对其它用户的表或视图的存取权限.(是针对表或视图而言的). 二.系统权限管理:1.系统权限分类:DBA: 拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构. RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构. CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构. 对于普通用户:授予connec

Oracle SGA详解

SGA(SYSTEM Global Area )系统全局区 l 数据高速缓存 在Oracle进行数据处理的过程中,代价最昂贵的就是物理 I/O操作了.同样的数据从内存中得到要比从磁盘上读取快的多.因此,优化Oracle的一个重要的目标就是尽可能的降低物理 I/O操作. Oracle的 Buffer Cache用于缓存从磁盘中读取的数据,当 Oracle需要查找某些信息的时候,首先会在 BufferCache中寻找,如果找到了,则直接将结果返回.如果找不到,则需要对磁盘进行扫描, Oracle将在

Oracle ROWID详解

1.ROWID定义 ROWID:数据库中行的全局唯一地址 对于数据中的每一行,rowid伪列返回行的地址.rowid值主要包含以下信息: 对象的数据对象编号 该行所在的数据文件中的数据块 该行中数据块的位置(第一行是0) 数据行所在的数据文件(第一个文件是1).该文件编号是相对于表空间. 通常来说,一个rowid值唯一标识数据中的一行.然而,存储在同一聚簇中不同的表可以有相同的rowid. 2.扩展ROWID 从Oracle 8i开始使用扩展rowid标识行物理地址 扩展rowid使用base6

Spring3.1 jar包详解和依赖关系

一.包的详解: Spring 3.1的jar包和以前的不一样,新版本的jar包把原来的包分解了,功能分工很明确: org.springframework.aop-3.1.1.RELEASE.jar ---- ---- spring面向切面编程,提供AOP(面向切面编程) org.springframework.asm-3.1.1.RELEASE.jar ---- ---- spring独立的asm程序 [spring2.5.6的时候需要asmJar 包,3.0开始提供他自己独立的asm.jar

jquery validate 详解二

原文:http://blog.sina.com.cn/s/blog_608475eb0100h3h2.html 这里只是第二篇,前面的内容请参阅上一篇 五.常用方法及注意问题 1.用其他方式替代默认的SUBMIT 1 $().ready(function() { 2 $("#signupForm").validate({ 3 submitHandler:function(form){ 4 alert("submitted"); 5 form.submit(); 6