2017-10-13 251 views
0

我创建Oracle中的存储过程 - 见下文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有什么问题吗?

回答

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中“在作用域内”,对于调用者而言是不可见的 - 匿名块)。