ORA-01722: 无效编号 当我尝试执行存储过程时。甲骨文错误

Posted

技术标签:

【中文标题】ORA-01722: 无效编号 当我尝试执行存储过程时。甲骨文错误【英文标题】:ORA-01722: invalid number When I try to execute an store procedure. Oracle error 【发布时间】:2020-01-14 21:49:37 【问题描述】:

我知道当我尝试将无效字符转换为数字时会发生 ORA-01722。例如:“a123”。在这种情况下,我只尝试创建一个 where 条件,其中参数是表的 ID,参数是根据表类型定义的。

PROCEDURE SP_CPR_AGRUPAR_COMPRA(ID_SOLICITUD IN cpr_solicitud.id%type, ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN

 UPDATE cpr_solicitud
 SET ID_GRUPO=ID_GRUPO
 WHERE id=ID_SOLICITUD;

END SP_CPR_AGRUPAR_COMPRA;

我尝试使用 TO_NUMBER 函数格式化 ID_SOLICITUD,但错误仍然存​​在。像这样的:

UPDATE cpr_solicitud
SET ID_GRUPO=ID_GRUPO
WHERE id=TO_NUMBER(ID_SOLICITUD);

我做了一个直接传递信息的测试,它可以工作。

UPDATE cpr_solicitud SET ID_GRUPO = 18 WHERE id = 942000;

我做了很多测试,结论是错误与ID_SOLICITUD参数有关。我不知道为什么,但如果我通过了 ID_GRUPO 并离开了 ID_SOLICITUD,它就可以工作。

成功了:

UPDATE cpr_solicitud
SET ID_GRUPO=ID_GRUPO
WHERE id=1

这行不通:

UPDATE cpr_solicitud
SET ID_GRUPO=1
WHERE id=TO_NUMBER(ID_SOLICITUD);

【问题讨论】:

cpr_solicitud.id 的数据类型是什么?另外,SET ID_GRUPO=ID_GRUPO 可能没有做你想做的事。 你的表是否也有一个名为ID_SOLICITUD的列? @BobJarvis-ReinstateMonica 表中的数据类型是 NUMBER(38,0)。 ID_GRUPO。它是与具有相同数据类型的其他表的外键(NUMBER(38,0)) @AlexPoole 是的。但在这种情况下 ID_SOLICITUD 是表中的 ID。这只是参数名称(我知道,这可能会造成混淆) 不,不是“可能”;它混乱的,所以Oracle 有固定的规则来解决混乱。 You're seeing the documented behaviour. 【参考方案1】:

As stated in the documentation:

如果 SQL 语句引用的名称既属于列又属于局部变量或形参,则列名优先。

注意:当变量或参数名称被解释为列名称时,可能会无意中删除、更改或插入数据。

在您的代码中,

SET ID_GRUPO=ID_GRUPO

正如@Bob 暗示的那样,显然属于该警告。与过滤器匹配的每一行都将使用它的当前值进行更新(即没有任何变化),而不是传递给过程的值。正如您在评论中确认的那样,该表也有一个名为 ID_SOLICITUD 的列,所以也有:

WHERE id=ID_SOLICITUD;

您收到错误是因为它隐式地将 列值ID_SOLICITUD(可能不是数字)转换为数字,以便可以与 id 进行比较。 ID_SOLICITUD 参数值没有被使用,因此它的数据类型不相关。你正在有效地做:

UPDATE cpr_solicitud
SET cpr_solicitud.ID_GRUPO=cpr_solicitud.ID_GRUPO
WHERE cpr_solicitud.id=cpr_solicitud.ID_SOLICITUD;

这显然不是你想要的。如果你在其上运行该语句,你会得到同样的错误。

您可以在变量名称前加上它们实际属于的对象:

PROCEDURE SP_CPR_AGRUPAR_COMPRA(ID_SOLICITUD IN cpr_solicitud.id%type, ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN

 UPDATE cpr_solicitud
 SET ID_GRUPO=SP_CPR_AGRUPAR_COMPRA.ID_GRUPO
 WHERE id=SP_CPR_AGRUPAR_COMPRA.ID_SOLICITUD;

END SP_CPR_AGRUPAR_COMPRA;

或者(也许更简单、更安全)更改名称,例如带有一个简单的前缀:

PROCEDURE SP_CPR_AGRUPAR_COMPRA(p_ID_SOLICITUD IN cpr_solicitud.id%type, p_ID_GRUPO IN cpr_solicitud.ID_GRUPO%type ) AS
BEGIN

 UPDATE cpr_solicitud
 SET ID_GRUPO=p_ID_GRUPO
 WHERE id=p_ID_SOLICITUD;

END SP_CPR_AGRUPAR_COMPRA;

【讨论】:

感谢@Alex Poole。我真的不知道这件事。再次感谢您的帮助

以上是关于ORA-01722: 无效编号 当我尝试执行存储过程时。甲骨文错误的主要内容,如果未能解决你的问题,请参考以下文章

SQL ORA-01722: 无效号码

SELECT FROM AS 导致 ORA-01722: 无效号码

Oracle sql 错误 ora-01722 无效数字 ora-02063 前行来自

ORA-01722: 无效的数字 where 子句

ORA-01722 运行存储过程时出错

ORA-01722: 插入行时数字无效