程序包 Package

断开了依赖链

实验依赖关系:

<1> 首先不使用包

-- 创建表

CREATE table t (x int);

-- 创建视图

create view v as select * from t;

-- 创建存储过程

create procedure p
as
begin
    for x in (select * from v)
    loop
        null;
    end loop;
end;
/

-- 创建函数

create function f
return number
as
    l_cnt number;
begin
    select count(*) into l_cnt from t;
    return l_cnt;
end;
/

-- 查询他们之间的依赖关系

select name, type, referenced_name, referenced_type
  from user_dependencies
where referenced_owner = user
   and name in ('P','T','V','F')
order by name;

-- 目前得到的结果, 全部是 valid 的, 即全部是可用的

-- 测试, 当我修改了 表 t 以后,
alter table t add y number;

-- 确认一下现在对象的状态
SELECT OBJECT_NAME, object_type, status
   from user_objects
  where object_name in ('T','V','P','F');

-- 看一下上面得到的结果, 除了修改的表 t 以外, 全部是 invalid 的, 换句话说, 全部要重新确认, 编译等.

-- 接下来再创建一个存储过程 P2

create or replace procedure p2
as
begin
    p;
end;
/

-- 检查这时候各个对象的可用性

SELECT OBJECT_NAME, object_type, status
  from user_objects
where object_name in ('T','V','P','F', 'P2');

我们惊奇的发现, 居然除了 FUNCTION 剩下的全部又可用了,证明创建P2的过程中, 由于调用了P, 而P又使用了V,

-- 另外, 再看看依赖关系

select name, type, referenced_name, referenced_type
  from user_dependencies
where referenced_owner = user
   and name in ('P','T','V','F', 'P2')
order by name;

P2 –> P –> V –> T

显然, 编译 P2 不仅仅编译了P2, 它还编译了P 和 V.

-- 测试改变表t

alter table t add z number;

-- 查看各个对象的状态

发现除了表 T 意外, 又全部不可用了, 就连新创建的P2也不可用了, 因为P2依赖于P, 这是一个”链”

<2> 下面我们使用package

-- 清理现场

drop procedure p;
drop procedure p2;
drop function f;

-- 创建包 P1

create package p1
as
    procedure p;
end;
/

create package body p1
as
procedure p
as
begin
    for x in (select * from v)
    loop
        null;
    end loop;
end;
end p1;
/

-- 创建包 P2

create package p2
as
    procedure p;
end;
/

create package body p2
as
procedure p
as
begin
    p1.p;
end;
end p2;
/

-- 查询依赖关系

select name, type, referenced_name, referenced_type
  from user_dependencies
where referenced_owner = user
   and name in ('P','T','V','F', 'P2', 'P1')
order by name;

注意: 这时 PACKAGE BODY P2 依赖于 PACKAGE P1, 不依赖于程序包体, 而依赖于程序包(接口), 这表示P1的程序包体可以变成无效, 而不影响别的东西.

-- 目前, 各个对象的状态

SELECT OBJECT_NAME, object_type, status
   from user_objects
  where object_name in ('T','V','P','F', 'P2', 'P1');

-- 测试修改表

alter table t add a number;

-- 再看各个对象的状态

SELECT OBJECT_NAME, object_type, status
   from user_objects
  where object_name in ('T','V','P','F', 'P2', 'P1');

发现只有 P1 的PACKAGEBODY, V 两个对象不可用, 因为这两个对象都依赖于表 t.

现在, 只要说明(程序包的接口)不改变, 系统中依赖代码就不会变成无效, 这可以使得改动局部化而不会导致系统大量重新编译.

Oracle 会执行自动依赖编译, 所以, 当我们执行 exec p2.p , 以上所有的对象都会变成可用状态.

增加了名字空间

支持重载

支持封装

支持会话永久变量

支持精心制作的启动代码

把相关的功能组织在一起

使用静态SQL

如果利用静态 SQL 可以达到目的, 那么就尽量不要使用动态 SQL.

静态SQL VS 动态SQL: 静态SQL的好处, 编译时检查, PL/SQL验证数据类型, 数据字典中建立维护依赖, 基础对象改变, 代码会自动适应, 静态SQL可以实现分析一次, 多次执行, 静态SQL更快.

寻找替换动态SQL: 例如下面的动态SQL , 可以通过静态的PL/SQL function 来替换

create or replace function get_value_dyn
(p_empno in number, p_cname in varchar2)
return varchar2
as
l_value varchar2(4000);
begin
execute immediate
'select ' || p_cname || 'from emp where empno = :x'
into l_vale
using p_empno; return l_value;
end;
/

替换:

create or replace function get_value_static
(p_empno in number, p_cname in varchar2)
return varchar2
as
l_value varchar2(4000);
begin
select decode(upper(p_cname),
'ENAME', ename,
'EMPNO', empno)
into l_value
from emp
where empno = p_empno; return l_value;
end;
/

使用调用者权限

执行PL/SQL方法两种:

使用定义者权限, 表示执行过程时利用存储过程拥有者的基本权限执行SQL.

使用调用者权限, 表示执行过程时以调用者用户当前的权限执行SQL语句.

基本上可以说, 使用定义者权限就可以了, 如果你考虑安全问题, 那么用别的方法来解决, 这里大师推荐使用定义者权限来执行. 在开发程序阶段, 可以使用调用者权限来进行测试之类的. 因为你使用了调用者权限, 那么就使用了调用者的模式, 比如, 同样有个table 名为 t, 在你测试的模式下也有一个t, 那么,  程序开发阶段使用调用者权限, 使用的是当前开发用户模式下的t, 而真正到了生产环境, 使用的是生产环境下的 t.

隐式游标还是显示游标

隐式游标效率要高于显示游标, 但是在大批量的操作时, 必须使用显示游标.

以下两种情况, 可以使用隐式游标:

-- 1 , 单行取的选择, 在查询中最多检索出一行时

例如: select <column1, column2 …> into <variable1, value2 …> from <table>

--2 , 结果集, 在检索有限数目的行时, (10 行以内)

例如: for x in (select … from … where …) loop  process… end loop;  -- 10 行以内

09 高效的PL/SQL程序设计的更多相关文章

  1. [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)

    原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...

  2. 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》

    本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...

  3. Oracle数据库之PL/SQL程序设计简介

    PL/SQL程序设计简介 一.什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写. ORACLE的SQL ...

  4. oracle pl/sql 程序设计 历史笔记整理

    20131016 周三 oracle pl/sql 程序设计 第2章 创建并运行pl/sql代码 sqlplus yjkhecc/yjkhecc@10.85.23.92:1521/orcl 在java ...

  5. PL/SQL程序设计

    1 PL/SQL简介 1 什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写.PL/SQL是对SQL语言 ...

  6. PL/SQL程序设计、流程控制

    PL/SQL是 Procedure Language & Structured Query Language 的缩写 PL/SQL是对SQL语言存储过程语言的扩展 PL/SQL程序由三个块组成 ...

  7. oracle PL/SQL程序设计

    declare 说明部分    (变量说明,光标申明,例外说明 ] begin 语句序列   (DML语句]… exception 例外处理语句 End; /

  8. ORACLE PL/SQL编程详解

    ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...

  9. ORACLE PL/SQL编程详解(转)

    原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...

随机推荐

  1. asp.net中调用javascript自定义函数的方法(包括引入JavaScript文件)总结

    通常javascript代码可以与HTML标签一起直接放在前 端页面中,但如果JS代码多的话一方面不利于维护,另一方面也对搜索引擎不友好,因为页面因此而变得臃肿:所以一般有良好开发习惯的程序员都会把 ...

  2. SQL中join的用法

    关于sql语句中的连接(join)关键字,是较为常用而又不太容易理解的关键字,下面这个例子给出了一个简单的解释 --建表table1,table2:create table table1(id int ...

  3. SDUT 2416:Fruit Ninja II

    Fruit Ninja II Time Limit: 5000MS Memory limit: 65536K 题目描述 Have you ever played a popular game name ...

  4. 周赛-Expression 分类: 比赛 2015-08-02 09:35 3人阅读 评论(0) 收藏

    A. Expression time limit per test1 second memory limit per test256 megabytes inputstandard input out ...

  5. 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)

    斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...

  6. C语言培训第一天

    下面是一些命令,先来谈谈今天的若干收获吧! 计算机中的一切文件都是以二进制补码的形式存在,问题也就来了. 第一个问题 如果我们给一个无符号的数赋值一个负数,他会读取到什么,又会输出什么?(似乎问题和上 ...

  7. 在Visual Studio中使用MonoTouch开发iOS应用程序

    前段时间在工作机上装了Mac OS X,这主要是因为我最近需要开发iPhone应用程序.虽然Xcode,Objective C一定是开发iOS应用程序的主流,但是经过一番考虑,我还是决定尝试一下使用M ...

  8. BFC——一个我们容易忽视掉的布局神器

      今天给大家说说BFC这个概念,在说概念前,先给大家看个例子: 首先,定义三个div块元素   效果: 我们发现,块级元素的排列顺序是从上往下,一块接着一块,在w3c中,是这样解释block-lev ...

  9. SqlSever基础 union 联合查询,厉害的并集 重复项只显示一个 两个查询结果并在一起后排序

    镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...

  10. 1:CSS中一些@规则的用法小结 2: @media用法详解

    第一篇文章:@用法小结 第二篇文章:@media用法 第一篇文章:@用法小结 这篇文章主要介绍了CSS中一些@规则的用法小结,是CSS入门学习中的基础知识,需要的朋友可以参考下     at-rule ...