RESTRICT_REFERENCES和触发器

Pab*_*blo 7 sql oracle plsql oracle11g

我将PRAGMA RESTRICT_REFERENCES添加到包中的过程(例如,RNPS).该过程实现在表中插入一行.

该表具有before insert触发器.该触发器从包中读取变量并将其放入:new.my_column.

我可以毫无问题地编译包体,即使它实际上是从包变量中读取值.

当我执行该程序时,它实际上是有效的.但这是发展的过程,通常没有多个同时连接.我担心这可能会在生产环境中失败.

那么,我应该担心,还是这实际上有用?

示例代码:

CREATE TABLE MY_TABLE 
(
  ID VARCHAR2(20) NOT NULL 
, USER_ID VARCHAR2(50) 
, CONSTRAINT MY_TABLE_PK PRIMARY KEY 
  (
    ID 
  )
  ENABLE 
);

CREATE OR REPLACE PACKAGE PUSER IS

    PROCEDURE saveUser(
            pUserId VARCHAR2
        );
    PRAGMA RESTRICT_REFERENCES (saveUser, WNDS, RNDS, RNPS);

    FUNCTION getUser RETURN VARCHAR2;
    PRAGMA RESTRICT_REFERENCES (getUser, WNDS, RNDS, WNPS);

END PUSER;

CREATE OR REPLACE PACKAGE BODY PUSER AS

    userId VARCHAR2(50);

    PROCEDURE saveUser(
            pUserId VARCHAR2
        ) IS
    BEGIN
        userId := pUserId;
    END saveUser;

    FUNCTION getUser RETURN VARCHAR2 IS
    BEGIN
        RETURN userId;
    END getUser;

END PUSER;


CREATE OR REPLACE PACKAGE MY_PACKAGE IS

    PROCEDURE insertMyTable(
            pId VARCHAR2
        );
    PRAGMA RESTRICT_REFERENCES (insertMyTable, RNPS);

END MY_PACKAGE;

CREATE OR REPLACE PACKAGE BODY MY_PACKAGE AS

    PROCEDURE insertMyTable(
            pId VARCHAR2
        ) IS
    BEGIN
        INSERT INTO MY_TABLE(id) VALUES(pId);
    END insertMyTable;
END MY_PACKAGE;

CREATE OR REPLACE TRIGGER MY_TABLE_TRIGGER
BEFORE INSERT ON MY_TABLE FOR EACH ROW
DECLARE
BEGIN
    :new.USER_ID := PUSER.getUser;
END MY_TABLE_TRIGGER;
Run Code Online (Sandbox Code Playgroud)

编辑:我知道不推荐使用RESTRICT_REFERENCES,但知道这对现有代码仍然有用.

Mar*_*onk 1

RNPS仅对函数有用,因为它告诉编译器,如果同时没有更改包状态(或其他编译指示的数据库状态),则函数的返回值在调用之间不会更改。它允许缓存,但以比使用更隐式的方式RESULT_CACHEor更隐式的方式DETERMINISTIC(现在是告诉优化器期望什么的首选方式)。

由于您在程序中使用它,所以这并不重要。您可以安全地继续操作,而无需更改包规格。然而,由于您(或您的继任者)可能会在一年后问自己同样的问题,因此您不妨立即更改软件包。