pl / sql存储过程:参数名称与列名称相同

时间:2009-10-22 15:07:40

标签: oracle stored-procedures plsql

我有一个像这样的存储过程

procedure P_IssueUpdate
(
    Id in integer,
    ModifiedDate in date,
    Solution in varchar2
) AS
BEGIN
update T_Issue
Set
  ModifiedDate = ModifiedDate,
  Solution = Solution
where id = id;
END P_IssueUpdate;

我的问题是参数名称与表列名称相同。 有没有办法指示sql“=”之后的值应该是参数而不是列?

感谢您的帮助

4 个答案:

答案 0 :(得分:40)

您可以使用以下过程的名称为参数和变量名添加前缀:

SQL> declare
  2     procedure p (empno number) is
  3        ename varchar2(10);
  4     begin
  5        select ename
  6        into p.ename
  7        from emp
  8        where empno = p.empno;
  9        dbms_output.put_line(p.ename);
 10     end;
 11  begin
 12     p (7839);
 13  end;
 14  /
KING

PL/SQL procedure successfully completed.

答案 1 :(得分:6)

您所描述的内容称为variable shadowing。它可以用任何语言发生。您获得了良好的解决方法,但常见的解决方案是设计一个命名方案,以便永远不会发生。

例如,将列命名为不带前缀,并使变量的前缀取决于其范围(参数P_,局部变量L_,全局包变量G_等等......)通过为您提供更多信息,这将带来额外的好处,即使代码更具可读性。

答案 2 :(得分:4)

我找到了解决方案。它通过完全限定参数来工作:

procedure P_IssueUpdate
(
    Id in integer,
    ModifiedDate in date,
    Solution in varchar2
) AS
BEGIN
update T_Issue
Set
  ModifiedDate = P_IssueUpdate.ModifiedDate,
  Solution = P_IssueUpdate.Solution
where id = P_IssueUpdate.id;
END P_IssueUpdate;

答案 3 :(得分:3)

RE Vincent关于添加前缀的答案 - 该解决方案有效,直到某人修改表并添加名称恰好与参数名冲突的列。并非每个人都经历了每行代码,以确保他们的表修改不会与变量或参数名称冲突。 Oracle的建议是限定SQL查询中的每个参数或变量名称。

如果您正在使用匿名块(在过程之外),则可以命名块并以这种方式限定变量:

<<MY_BLOCK>>
declare
   X   sys.USER_TABLES%rowtype;
   Y   sys.USER_TABLES.TABLE_NAME%type := 'some_table_name';
begin
   select UT.*
   into   MY_BLOCK.X
   from   sys.USER_TABLES UT
   where  UT.TABLE_NAME = MY_BLOCK.Y;
end MY_BLOCK;