我在Oracle中创建了一个存储过程 - 见下文
create or replace PROCEDURE REMOVE_CUSTOMER
(
cus_id IN NUMBER
)
AS
BEGIN
DELETE FROM CUSTOMER WHERE CUSTOMER.CUS_ID = cus_id;
END;

我按照下面的方式执行了它。
DECLARE
CUS_ID NUMBER;
BEGIN
CUS_ID := 192981;
REMOVE_CUSTOMER(CUS_ID => CUS_ID);
END;

它假设仅删除客户192981。但是,表中的所有客户都被删除了。谁能告诉我pl / sql有什么问题?
答案 0 :(得分:1)
程序中的陈述:
DELETE FROM CUSTOMER WHERE CUSTOMER.CUS_ID = cus_id;
查询解析器必须标识右侧的cus_id
。如果表中有一个名称的列,那么这是第一选择。这就是删除所有内容的原因; RHS被解释为customer.cus_id
。
如果表中没有这样的列,第二次猜测将是过程中定义的变量。但这只是第二种选择,而不是第一种选择。
最佳做法是为过程变量使用不同的名称,可以在列名称前加p_
(参数)或i_
(输入):p_cus_id
。
您可以为过程变量使用相同的名称,但是您必须在SQL语句中完全限定它:
where customer.cus_id = remove_customer.cus_id
实际上你不需要在左手边获得资格;这将有效:
where cus_id = remove_customer.cus_id
相比之下,您在匿名块中执行的操作(当您调用该过程时)不会导致问题。使用列名作为匿名块中声明的变量的名称仍然是一种不好的做法,但是当您从匿名块调用存储过程时,不会混淆哪个CUS_ID是存储的输入程序;它不能是表中的列名,也不能是SP中的变量(只在SP中“在范围内”,调用者看不到 - 匿名块)。