我知道当我尝试将无效字符转换为数字时会发生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);
如文档中所述:
如果 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;