Ste*_*ein 4 sql oracle plsql function
我创建了一个包,该包在同一页面内的 SELECT 语句中执行我的函数:
CREATE OR REPLACE PACKAGE p
AUTHID DEFINER
IS
FUNCTION f
RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY p
IS
FUNCTION ff RETURN NUMBER
IS
BEGIN
RETURN 73;
END;
FUNCTION f RETURN NUMBER
IS
l_number NUMBER;
BEGIN
SELECT 42 INTO l_number
FROM DUAL
WHERE ff () = 73;
RETURN l_number;
END;
END;
/
BEGIN
DBMS_OUTPUT.put_line (p.f);
END;
/
Run Code Online (Sandbox Code Playgroud)
但是当我尝试执行该函数时,出现 PLS-00231 编译错误:
BEGIN
dbms_output.put_line (P.F);
END;
/
PLS-00231: function 'FF' may not be used in SQL
Run Code Online (Sandbox Code Playgroud)
该函数就在那里声明。它不执行任何非查询 DML。它的标头中没有任何特定于 PL/SQL 的数据类型。
为什么 SQL 不能使用/看到它?
这是底线:
如果要从 SQL 语句中调用函数,则它必须在模式级别 (CREATE FUNCTION) 中声明或在包的规范中定义。即使您的 SQL 语句位于与调用的函数相同的包中的子程序中,也是如此。
因此,如果我按如下方式更改包规范,公开以前的私有函数,一切都很好:
CREATE OR REPLACE PACKAGE p AUTHID DEFINER
IS
FUNCTION f RETURN NUMBER;
FUNCTION ff RETURN NUMBER;
END;
/
Run Code Online (Sandbox Code Playgroud)
请注意,有趣的是,您不必在静态 SQL 语句中用包名限定函数名。PL/SQL 编译器在将语句传递给 SQL 引擎之前对其进行排序。
但是,如果动态执行 SQL,则需要包名称,如下所示:
FUNCTION f RETURN NUMBER
IS
l_number NUMBER;
BEGIN
EXECUTE IMMEDIATE
'SELECT 42 FROM DUAL WHERE p.ff () = 73'
INTO l_number;
RETURN l_number;
END;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5308 次 |
最近记录: |