PL/SQL 错误地违反了 Pragma
PL/SQL Pragma incorrectly violated
我的包头代码如下所示:
CREATE OR REPLACE PACKAGE INST_PKG IS
...
FUNCTION Check_View (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN;
PRAGMA restrict_references (Check_View, WNDS);
...
END INST_PKG;
函数体定义如下:
CREATE OR REPLACE PACKAGE BODY INST_PKG IS
....
FUNCTION View_Exist (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN
IS
ck_ NUMBER := 0;
CURSOR check_view IS
SELECT 1
FROM user_views uv
WHERE uv.view_name = upper(view_name_);
BEGIN
OPEN check_view;
FETCH check_view INTO ck_;
IF check_view%FOUND THEN
CLOSE check_view;
RETURN true;
ELSE
CLOSE check_view;
RETURN false;
END IF;
END View_Exist;
....
END INST_PKG;
当我尝试编译包主体时,收到如下错误消息:
Compilation errors for PACKAGE BODY INST_PKG
Error: PLS-00452: Subprogram 'VIEW_EXIST' violates its associated pragma
Line: 684
Text: FUNCTION View_Exist (
显然,我的"Write No Database State" pragma 没有被违反,因为函数中没有DML 语句。有人见过这样的行为吗?
当然,我可以删除 Pragma 引用,但这有点违背了目的。
值得注意的是:
我的数据库已从 Oracle 10g 实例导出,并已重新导入到 12c。 (如您所想,这是升级测试)。因此,我在 Oracle 12c 上收到上述错误。
我尝试删除并重新创建包,但这似乎并没有改变什么。
我有一种感觉,可能某个地方的库引用被错误地导入了,因为当我删除这个包时,同样的错误出现在另一个包含同名函数的包中。但是当我重新创建 INST_PKG 时,第二个包编译正常,就好像第一个包中的问题掩盖了它在第二个包中被标记一样。
感谢@MuhammadMuzzam 为我指明正确的方向。问题是 user_views
有一些引用显然违反了 Oracle 12 中的 Pragma。
似乎是一个已知问题:
https://community.oracle.com/thread/3650610?start=0&tstart=0
从您显示的 link 中可以看出,该问题是 USER_VIEWS 中的错误造成的(Oracle 忘记将 PRAGMA restrict_references 与 NO_ROOT_SW_FOR_LOCAL 相关联) .
在这种情况下,您可以确定您的函数不违反 WNDS 断言(不写入数据库),因此只需使用 TRUST 选项在编译期间禁用断言验证:
PRAGMA restrict_references (Check_View, WNDS, TRUST);
我的包头代码如下所示:
CREATE OR REPLACE PACKAGE INST_PKG IS
...
FUNCTION Check_View (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN;
PRAGMA restrict_references (Check_View, WNDS);
...
END INST_PKG;
函数体定义如下:
CREATE OR REPLACE PACKAGE BODY INST_PKG IS
....
FUNCTION View_Exist (
view_name_ IN VARCHAR2 ) RETURN BOOLEAN
IS
ck_ NUMBER := 0;
CURSOR check_view IS
SELECT 1
FROM user_views uv
WHERE uv.view_name = upper(view_name_);
BEGIN
OPEN check_view;
FETCH check_view INTO ck_;
IF check_view%FOUND THEN
CLOSE check_view;
RETURN true;
ELSE
CLOSE check_view;
RETURN false;
END IF;
END View_Exist;
....
END INST_PKG;
当我尝试编译包主体时,收到如下错误消息:
Compilation errors for PACKAGE BODY INST_PKG
Error: PLS-00452: Subprogram 'VIEW_EXIST' violates its associated pragma
Line: 684
Text: FUNCTION View_Exist (
显然,我的"Write No Database State" pragma 没有被违反,因为函数中没有DML 语句。有人见过这样的行为吗?
当然,我可以删除 Pragma 引用,但这有点违背了目的。
值得注意的是: 我的数据库已从 Oracle 10g 实例导出,并已重新导入到 12c。 (如您所想,这是升级测试)。因此,我在 Oracle 12c 上收到上述错误。
我尝试删除并重新创建包,但这似乎并没有改变什么。
我有一种感觉,可能某个地方的库引用被错误地导入了,因为当我删除这个包时,同样的错误出现在另一个包含同名函数的包中。但是当我重新创建 INST_PKG 时,第二个包编译正常,就好像第一个包中的问题掩盖了它在第二个包中被标记一样。
感谢@MuhammadMuzzam 为我指明正确的方向。问题是 user_views
有一些引用显然违反了 Oracle 12 中的 Pragma。
似乎是一个已知问题:
https://community.oracle.com/thread/3650610?start=0&tstart=0
从您显示的 link 中可以看出,该问题是 USER_VIEWS 中的错误造成的(Oracle 忘记将 PRAGMA restrict_references 与 NO_ROOT_SW_FOR_LOCAL 相关联) .
在这种情况下,您可以确定您的函数不违反 WNDS 断言(不写入数据库),因此只需使用 TRUST 选项在编译期间禁用断言验证:
PRAGMA restrict_references (Check_View, WNDS, TRUST);