关于PRAGMA RESTRICT_REFERENCES 的理解

来源:互联网 发布:软件 竞业协议 编辑:程序博客网 时间:2024/05/16 08:49

一 介绍:

在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;
/





原创粉丝点击