0

如果 WHERE 如下所示,则以下 PL/SQL 代码的行为会有所不同:

WHERE USERNAME = 'aaaaaa'

如果看起来像这样,则不同:

WHERE USERNAME = userName

为什么结果不一样 if userName := 'aaaaaa'?我究竟做错了什么?谢谢!

declare
  isFound  NUMBER;
  userName VARCHAR2(30);
begin
  isFound  := 0;
  userName := 'aaaaaa';

  SELECT COUNT(*)
    INTO isFound
    FROM MyTable
   WHERE USERNAME = 'aaaaaa' -- userName
     AND ROWNUM = 1;

  IF isFound > 0 THEN
    dbms_output.put_line('Found');
  ELSE
    dbms_output.put_line('Not found');
  END IF;

end;
4

2 回答 2

4

在这个版本中:

  SELECT COUNT(*)
    INTO isFound
    FROM MyTable
   WHERE USERNAME = userName
     AND ROWNUM = 1;

...该表的USERNAME列正在与其自身进行比较,因此它将始终匹配。您没有将其与局部变量进行比较。如果您想这样做,您需要为该列赋予不同的名称:

declare
  isFound  NUMBER;
  localUserName VARCHAR2(30);
begin
  isFound  := 0;
  userName := 'aaaaaa';

  SELECT COUNT(*)
    INTO isFound
    FROM MyTable
   WHERE USERNAME = localUserName
     AND ROWNUM = 1;

  IF isFound > 0 THEN
    dbms_output.put_line('Found');
  ELSE
    dbms_output.put_line('Not found');
  END IF;

end;

或者正如 David Aldridge 建议的那样,使用标签来区分局部变量和表列:

<<local>>
declare
  isFound  NUMBER;
  userName MyTable.USERNAME%TYPE;
begin
  isFound  := 0;
  userName := 'aaaaaa';

  SELECT COUNT(*)
    INTO isFound
    FROM MyTable
   WHERE USERNAME = local.userName
     AND ROWNUM = 1;
...

您也可以将这种方法与命名块一起使用;如果这是在函数内部,则可以将局部变量称为function_name.variable_name. 由于这是一个匿名块,因此标签的作用与function_name本质上相同。

该文档有一个关于名称解析的部分

于 2013-09-18T15:12:07.643 回答
2

您可以使用标签。

<<the_code>>
declare
  isFound  NUMBER;
  userName VARCHAR2(30);
begin
  isFound  := 0;
  userName := 'aaaaaa';

  SELECT COUNT(*)
    INTO isFound
    FROM MyTable
   WHERE USERNAME = the_code.userName
     AND ROWNUM = 1;

  IF isFound > 0 THEN
    dbms_output.put_line('Found');
  ELSE
    dbms_output.put_line('Not found');
  END IF;

end;
于 2013-09-18T15:30:41.550 回答