09 高效的PL/SQL程序设计
程序包 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程序设计的更多相关文章
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- 每周一书《Oracle 12 c PL(SQL)程序设计终极指南》
本周为大家送出的书是<Oracle 12 c PL(SQL)程序设计终极指南>,此书由机械工业出版社出版, 孙风栋,王澜,郭晓惠 著. 内容简介: <Oracle 12c PL/SQ ...
- Oracle数据库之PL/SQL程序设计简介
PL/SQL程序设计简介 一.什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写. ORACLE的SQL ...
- oracle pl/sql 程序设计 历史笔记整理
20131016 周三 oracle pl/sql 程序设计 第2章 创建并运行pl/sql代码 sqlplus yjkhecc/yjkhecc@10.85.23.92:1521/orcl 在java ...
- PL/SQL程序设计
1 PL/SQL简介 1 什么是PL/SQL? PL/SQL是 Procedure Language & Structured Query Language 的缩写.PL/SQL是对SQL语言 ...
- PL/SQL程序设计、流程控制
PL/SQL是 Procedure Language & Structured Query Language 的缩写 PL/SQL是对SQL语言存储过程语言的扩展 PL/SQL程序由三个块组成 ...
- oracle PL/SQL程序设计
declare 说明部分 (变量说明,光标申明,例外说明 ] begin 语句序列 (DML语句]… exception 例外处理语句 End; /
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- ORACLE PL/SQL编程详解(转)
原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...
随机推荐
- hdwiki 的模板和标签
模版和标签 HDWiki模版标签可以让用户更方便.更容易的在页面中调用HDWiki的数据. HDWiki的三种标签:1.循环标签 {hdwiki:doclist...}{/hdwiki} ...
- layer
一款实用的web提示框架!下面是实用这款框架的实例 html代码 <p class='layer_notice'>我们是否是好惹的</p> <input type=&qu ...
- js判断用户浏览器是PC还是手机,自动跳转
browserRedirect(); function browserRedirect() { var sUserAgent = navigator.userAgent.toLowerCase(); ...
- http模式
http遵守请求响应模式: 请求: 请求行:HTTP方法-请求的URL-HTTP版本 请求行 空行 消息体 响应: 状态行:HTTP版本-响应码-响应描述 响应头 空行 消息体 其他的重点: http ...
- js的选择星级评分插件
需要引入jquery和raty的js,并且低版本的jquery可能会出现样式问题,或者点击没反应,可换高版本试试 raty文档及下载: http://www.wbotelhos.com/raty/ 把 ...
- 如何借助浏览器Console使用Js进行定位和操作元素
在进行Selenium自动化过程中,我们很难避免一些webdriver 很难定位到的一些元素(如:默认隐藏属性元素),那对于一些比较难定位到的元素,有什么好的解决办法? 其实我们都知道,Sel ...
- 巧用ViewPager 打造不一样的广告轮播切换效果
一.概述 如果大家关注了我的微信公众号的话,一定知道我在5月6号的时候推送了一篇文章,文章名为Android超高仿QQ附近的人搜索展示(一),通过该文可以利用ViewPager实现单页显示多个Item ...
- 2016年12月9日 星期五 --出埃及记 Exodus 21:4
2016年12月9日 星期五 --出埃及记 Exodus 21:4 If his master gives him a wife and she bears him sons or daughters ...
- IOS文字属性备注
// Predefined character attributes for text. If the key is not in the dictionary, then use the defau ...
- 【Javascript】列表查询页面,简单地保存上一次查询的查询参数
开发中经常做一些查询参数 + 列表参数的功能,这些功能有时候需提供导出Excel,或带超链接到其他明细页面的功能点. 在一些交互性要求严格的系统,需求方会要求: 用户第一个输入某些查询条件进行列表查询 ...