ORA-01422 包/触发器的重新编译/重新验证(不执行)错误

Posted

技术标签:

【中文标题】ORA-01422 包/触发器的重新编译/重新验证(不执行)错误【英文标题】:ORA-01422 error on recompilation/revalidation (NOT EXECUTION) of package/trigger 【发布时间】:2014-05-21 12:28:15 【问题描述】:

我遇到了一个问题,我试图将一个包的执行权限授予另一个架构。

GRANT EXECUTE ON PP.PKG_PROF TO PPSERVICE;

看起来 Oracle 在授权之前尝试重新编译/重新验证包。但是它失败并出现以下错误:

GRANT EXECUTE ON PP.PKG_PROF TO PPSERVICE
Error report -
SQL Error: ORA-04045: errors during recompilation/revalidation of PP.PKG_PROF
ORA-20000: ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 83
04045. 00000 -  "errors during recompilation/revalidation of %s.%s"
*Cause:    This message indicates the object to which the following
       errors apply.  The errors occurred during implicit
       recompilation/revalidation of the object.    
*Action:   Check the following errors for more information, and
       make the necessary corrections to the object.

但是如果我查看第 83 行的代码,它会执行以下查询:

select 'x' into vtemp 
from cust_field_vals
where cust_fields = vin_cust_fields
and userid = vin_user_id;

vin_cust_fields 和 vin_user_id 是基于参数的值,在调用包中的过程时提供。

我的问题是:甲骨文到底在做什么?我了解“SELECT INTO” 理论上可以返回超过请求的行数(在这种情况下需要为一),但由于它不知道我的 vin 参数是什么,它如何进行评估?为什么重新编译/重新验证会抛出本质上相当于数据异常的异常,它甚至不应该查看我正在尝试做的事情(即:我没有尝试实际执行该过程)。

这不是我第一次看到这种情况,如果我没记错的话,我什至认为它也发生在重新编译触发器时(不是插入数据时)。

有什么想法吗?谢谢!

【问题讨论】:

您的数据库中是否有BEFORE GRANTAFTER GRANT DDL 触发器? 这是可能的(我们有一个 BEFORE DDL 来捕获 CREATE/REPLACE/DROP/ALTER),但我看不到它,因为我没有 SYS 访问权限并且我们的 DBA 离开了公司。我可以说我们的 20 个包中只有 2 个产生了这个错误(试图从 PROD 刷新我们的 UAT 环境)。我只是不确定 BEFORE DDL ON DATABASE 是否曾经移入 UAT。那么,如果是 SYS 级别的东西,编译所有其他包时不会产生异常吗? 如果不知道触发器的来源和数据库的详细信息,我就不能说。我的猜测是“第 83 行”是对 DDL 触发器中的一行的引用,而不是在包中,并且您正被 DDL 触发器中的错误所困扰。祝你好运。 现在我很困惑。如果我进入包体并尝试在那里编译,则使用 sql developer,它会产生相同的错误。但是,我先随机编译了包规范,然后是包体,它工作正常。然后拨款顺利通过。不知道为什么它会产生如此奇怪的错误。我猜甲骨文也无法告诉我规范也出了问题,并且被身体窒息了?!? +1 - 很高兴您解决了问题。 【参考方案1】:

显然,问题是我试图 GRANT 执行的包是“无效的”,即使没有实际的代码错误。首先编译正文会产生上述错误。如果我先手动编译包规范,然后正文,错误消失并且授权正常执行。包中没有代码错误,只是卡在了无法摆脱的无效状态。

【讨论】:

当 *** 允许我时,我会在 2 天内接受我的答案。同时,考虑一下这个答案!

以上是关于ORA-01422 包/触发器的重新编译/重新验证(不执行)错误的主要内容,如果未能解决你的问题,请参考以下文章

ORA-01422:- ORA-06512:

SELECT INTO 语句中的 ora-01422 错误

oracle中 触发器 \'SCOTT.TR_EMP\' 无效且未通过重新验证是啥错误

返回多于 1 行的 SELECT INTO - ORA-01422

PL/SQL ORA-01422 SELECT INTO 错误,Oracle 匿名块(NOVA 环境)

PL/SQL ORA-01422:精确提取返回的行数超过了请求的行数