忽略条件的更新语句

时间:2020-03-01 17:43:25

标签: sql oracle stored-procedures plsql where-clause

当我调用此过程时,它将更新表中的所有行,并且where条件将被忽略:

PROCEDURE update_sto_status (REQUEST_NUMBER     IN VARCHAR2,
                                     SHIPMENT_NUMBERS   IN VARCHAR2)
IS
BEGIN
    UPDATE apps.table1 OH
    SET OH.comments = SHIPMENT_NUMBERS
    WHERE OH.REQUEST_NUMBER = :REQUEST_NUMBER;
END;

4 个答案:

答案 0 :(得分:2)

除了表中的列之外,还应该给过程参数指定其他名称,否则它们会变得模棱两可。

基本上,在表达式中:

WHERE OH.REQUEST_NUMBER = REQUEST_NUMBER

等式右侧的REQUEST_NUMBER被理解为列名,而不是参数。这种情况始终是正确的,您最终将开始更新每条记录。

PROCEDURE update_sto_status (
    P_REQUEST_NUMBER   IN VARCHAR2,
    P_SHIPMENT_NUMBERS IN VARCHAR2
)
IS
BEGIN
    UPDATE apps.table1
    SET comments = P_SHIPMENT_NUMBERS
    WHERE request_number = P_REQUEST_NUMBER;
END;

答案 1 :(得分:2)

当PL / SQL变量或参数名称与表中的列名称发生冲突时,编译器始终会倾向于使用SQL语句中的列名称。在这种情况下,您已将参数命名为REQUEST_NUMBER,与名为REQUEST_NUMBER的列相同。因此,您的声明等同于

PROCEDURE update_sto_status (REQUEST_NUMBER     IN VARCHAR2,
                             SHIPMENT_NUMBERS   IN VARCHAR2)
IS
BEGIN
    UPDATE apps.table1 OH
    SET OH.comments = SHIPMENT_NUMBERS
    WHERE OH.REQUEST_NUMBER = OH.REQUEST_NUMBER;
END;

上面的比较总是正确的,因此每一行都会更新。

解决方案:前缀参数,其中pin代表输入参数,pout代表输出参数,pio代表输入/输出参数。然后你的程序就变成

PROCEDURE update_sto_status (pinREQUEST_NUMBER     IN VARCHAR2,
                             pinSHIPMENT_NUMBERS   IN VARCHAR2)
IS
BEGIN
    UPDATE apps.table1 OH
    SET OH.comments = pinSHIPMENT_NUMBERS
    WHERE OH.REQUEST_NUMBER = pinREQUEST_NUMBER;
END;

你很黄金。

答案 2 :(得分:1)

尝试避免使用:

  PROCEDURE update_sto_status (REQUEST_NUMBER     IN VARCHAR2,
                                 SHIPMENT_NUMBERS   IN VARCHAR2)
  IS
 BEGIN
   UPDATE apps.table1 OH
   SET OH.comments = SHIPMENT_NUMBERS
   WHERE OH.REQUEST_NUMBER = REQUEST_NUMBER;
 END;

答案 3 :(得分:0)

始终对所有内容都使用别名。

PROCEDURE update_sto_status (REQUEST_NUMBER     IN VARCHAR2,
                                 SHIPMENT_NUMBERS   IN VARCHAR2)
IS
BEGIN
    UPDATE apps.table1 OH
    SET OH.comments = update_sto_status.SHIPMENT_NUMBERS
    WHERE OH.REQUEST_NUMBER = update_sto_status.REQUEST_NUMBER;
END;