asa*_*n74 4 oracle plsql pragma package
我想创建一个Oracle Package和两个函数:public function(function_public)和private one(function_private).public函数在sql语句中使用私有函数.
没有编译指示代码不编译(PLS-00231: function 'FUNCTION_PRIVATE' may not be used in SQL)
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(100);
BEGIN
SELECT 'x' || function_private(x) INTO ret FROM dual;
return ret;
END;
END PRAGMA_TEST;
Run Code Online (Sandbox Code Playgroud)
如果我添加WNDS, WNPSpragma,代码将编译function_private.在我看来,pragma只能在包声明中使用,而不能在包体中使用,所以我必须function_private在包中声明:
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2;
PRAGMA RESTRICT_REFERENCES( function_private, WNDS, WNPS);
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(100);
BEGIN
SELECT 'x' || function_private(x) INTO ret FROM dual;
return ret;
END;
END PRAGMA_TEST;
Run Code Online (Sandbox Code Playgroud)
这个解决方案也让我function_private公开了.是否有解决方案将pragma添加到只能在包体中找到的函数?
更新:用一个工作(简化)示例替换伪代码.
UPDATE2:Rob van Wijk建议的代码中的错误修正.
你的问题与PRAGMAs无关.正如Rob所说,现代Oracle版本会自动处理大部分内容.
问题是你不能从SQL语句中调用私有函数,即使是嵌入在同一个包中的另一个子程序中的私有函数. 当PL/SQL执行SQL时,它会被传递给SQL引擎执行,这实际上会将您带到包的范围之外,因此它无法访问私有成员.
这编译很好 - 没有编译指示,但公开"私人"功能:
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(30);
BEGIN
SELECT 'x' || function_private(x) INTO ret FROM dual;
RETURN ret;
END;
END PRAGMA_TEST;
Run Code Online (Sandbox Code Playgroud)
如果要将该函数保持为私有,则需要查看是否可以重写public函数,以便在SQL语句之外完成对private函数的调用:
CREATE OR REPLACE PACKAGE PRAGMA_TEST AS
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2;
END PRAGMA_TEST;
CREATE OR REPLACE PACKAGE BODY PRAGMA_TEST AS
FUNCTION function_private(y IN VARCHAR2) RETURN VARCHAR2 IS
BEGIN
return 'z';
END;
FUNCTION function_public(x IN VARCHAR2) RETURN VARCHAR2 IS
ret VARCHAR2(30);
BEGIN
ret := function_private(x);
SELECT 'x' || ret INTO ret FROM dual;
RETURN ret;
END;
END PRAGMA_TEST;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12301 次 |
| 最近记录: |