关于PRAGMA RESTRICT_REFERENCES 的理解

一 介绍:

在Oracle application developer's guide --fundmental中9-60(oracle9i)有介绍,
copy一点给你先看看。
Using Pragma RESTRICT_REFERENCES
A function called from SQL statements must obey certain rules meant to control side effects.  To check for violations of the rules, you can use the pragma RESTRICT_REFERENCES.
The pragma asserts that a function does not read and/or write database tables and/or package variables. 
However, if the function body contains a dynamic INSERT, UPDATE, or DELETE statement, the function always violates the rules "write no database state" (WNDS) and "read no database state" (RNDS). That is because dynamic SQL statements are checked at run time,
not at compile time. In an EXECUTE IMMEDIATE statement, only the INTO clause can be checked at compile time for violations of RNDS.

二 例子:

CREATE or replace TABLE Accts(Yrs      NUMBER
,Amt      NUMBER
,Acctno   NUMBER
,Rte      NUMBER);

CREATE OR REPLACE PACKAGE Finance AS  -- package specification 
   FUNCTION Compound 
         (Years  IN NUMBER, 
          Amount IN NUMBER, 
          Rate   IN NUMBER) RETURN NUMBER; 
   PRAGMA RESTRICT_REFERENCES (Compound, WNDS, WNPS, RNDS, RNPS); 
END Finance; 

CREATE OR REPLACE PACKAGE BODY Finance AS  --package body 
   FUNCTION Compound 
         (Years  IN NUMBER, 
          Amount IN NUMBER, 
          Rate   IN NUMBER) RETURN NUMBER IS 
   BEGIN 
      RETURN Amount * POWER((Rate / 100) + 1, Years); 
   END Compound; 
                   -- no pragma in package body 
END Finance; 

--Later, you might call compound from a PL/SQL block, as follows:

DECLARE
   Interest NUMBER;
   Acct_id NUMBER;
BEGIN 
   SELECT Finance.Compound(Yrs, Amt, Rte)  -- function call       
   INTO   Interest       
   FROM   Accounts       
   WHERE  Acctno = Acct_id;

3 例子B

RESTRICT_REFERENCES,这个PRAGMA比较复杂,从字面上也看不到什么。

总的来说,它是一个程序辅助检验码,检查子程序的纯度(PURITY),帮助检验子程序是否有违反规则的地方。一般用在函数上,但当函数调用过程时,也要作相应的设置检查。这是为了避免当在DML语句上调用函数时正常执行不至于产生错误。

语法,PRAGMA RESTRICT_REFERENCES(function_name | default , )RNDS, WNDS, RNPS, WNPS) | , TRUST);

RNDS,WNDS,RNPS,WNPS可以同时指定。但当TRUST指定是,其它的被忽略。

DEFAUT是指作用在该程序包上的所有子程序,函数。

RNDS(Read No Database State),规定子程序不能读取任何的数据库状态信息。(即不会查询数据库的任何表,包括DUAL虚表)

RNPS(Read No Package State),规定子程序不能读取任何程序包的状态信息,如变量等。

WNDS(Write No Database State),规定子程序不能向数据库写入任何信息。(即不能修改数据库表)

WNPS(Write No Package State),规定子程序不能向程序包写入任何信息。(即不能修改程序包变量的值)

TRUST,指出子程序是可以相信的不会违反一个或多个规则。这个选项是需要的当用C或JAVA写的函数通过PL/SQL调用时,因为PL/SQL在运行是对它们不能检查。

这个编译指令只能在程序包及对象类型说明部分指定。

以下是个例子,在编译程序包体时报错,它违反了RNDS规则。

create or replace package test_pragma as
function test return date;
pragma restrict_references(test,rnds);
end;
/

create or replace package body test_pragma as
function test return date
as
vdate date;
begin
select sysdate into vdate from dual;
return vdate;
end test;
end test_pragma;
/

时间: 2024-10-16 05:25:43

关于PRAGMA RESTRICT_REFERENCES 的理解的相关文章

dbms_space.create_table_cost的unwrap解密和原理解析

Oracle提供了一系列PL/SQL package,包含了函数.存储过程,方便用户的使用,可以参考<Oracle Database PL/SQL Packages and Types Reference>手册,但其中一些存储过程的实现细节,Oracle并未透露,且对其进行了加密wrap.俗话说的话,"高手在民间",从Oracle 9i开始,就有牛人前辈,找出了解密unwrap的一些方法,便于我们学习Oracle的一些实现,对此我是佩服的五体投地. 但究竟我们是否可以找出,

PL/SQL9——包的创建与管理

http://blog.csdn.net/robinson_0612/article/details/6084475     包,是一个逻辑集合,是由PL/SQL类型以及PL/SQL子程序的集合.PL/SQL类型包括table类型,record类型.PL/SQL项则包括游标,游标 变量.PL/SQL子程序包括过程,函数等.可以说包可谓是包罗万象.是所有PL/SQL相关资源的汇总.     包的使用可以简化应用程序设计,实现信息掩藏,子程序重载等功能.     包的优点         1.模块化

PL/SQL --&amp;gt; 包重载、初始化

--========================== -- PL/SQL --> 包重载.初始化 --==========================       包的重载功能类似于C++中函数的重载功能,即拥有多个同名的子程序,每个同名子程序使用不同的参数.用户可以传递不同的参数来调 用同名但参数不同的子程序,此即为包的重载功能.简言之,不管传递什么样的参数,所完成的任务是相同的.假定需要查询部门所在的位置 ,输入参数部门编号或部门名称都会返回同样的结果.对外部程序而言,似乎是调用的同

ORACLE随机数DBMS_RANDOM包_oracle

简单得说,通过dbms_random包调用随机数的方法大致有4种: 1.dbms_random.normal     这个函数不带参数,能返回normal distribution的一个number类型,所以基本上随机数会在-1到1之间.     简单测试了一下,产生100000次最大能到5左右: Sql代码 declare i number:=; j number:=; begin for k in .. loop i:= dbms_random.normal; if i > j then j

[20150608]dbms_random.value.txt

[20150608]dbms_random.value.txt --11.2.0.3与11.2.0.4下,调用dbms_random.value存在很大的差异,测试看看: SCOTT@test> @ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -----------------------------------------------

itpub坛友问题--基于普通表或分区表创建索引,会占用临时表空间及何时回收临时表空间

个人简介: 8年oracle从业经验,具备丰富的oracle技能,目前在国内北京某专业oracle服务公司从事高级技术顾问.        服务过的客户:           中国电信           中国移动           中国联通           中国电通           国家电网           四川达州商业银行           湖南老百姓大药房           山西省公安厅           中国邮政           北京302医院         

深度解析dba_segments和sys.seg$中的细节差异(下)

继续昨天的内容 http://blog.itpub.net/23718752/viewspace-1624762/ 我们已经根据dba_segments和sys.seg$的不同发现最后的差距有2T左右,已经定位到了dba_segments的一些细节信息,可以发现其实还是一个层级的调用关系. 我们把SYS_DBA_SEGS是一个处于中间层的角色,它的定义是3个union all,可以从定义中看到,差别主要还是segment_type的不同,我们采用逐个击破的方法,一个一个来看.-->第一个子查询

【Http协议】深入理解HTTP协议

来源:http://www.blogjava.net/zjusuyong/articles/304788.html 深入理解HTTP协议 1. 基础概念篇 1.1 介绍   HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 194

深入理解C语言内存对齐

 这篇文章主要介绍了C语言内存对齐,有需要的朋友可以参考一下 一.内存对齐的初步讲解   内存对齐可以用一句话来概括:   "数据项只能存储在地址是数据项大小的整数倍的内存位置上"   例如int类型占用4个字节,地址只能在0,4,8等位置上.   例1:   代码如下: #include <stdio.h> struct xx{         char b;         int a;         int c;         char d; };   int m