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: 无效编号 当我尝试执行存储过程时。甲骨文错误的主要内容,如果未能解决你的问题,请参考以下文章
SELECT FROM AS 导致 ORA-01722: 无效号码