为什么这个基本的“Select Into”存储过程不起作用?

时间:2013-07-31 15:26:35

标签: sql oracle stored-procedures procedure declare

我正在运行Oracle SQL开发人员,我有以下存储过程。我对此很陌生,但我不确定为什么这不起作用:

CREATE OR REPLACE PROCEDURE CHECKDUPLICATE(
       username1 IN USERS.USERNAME%TYPE,
       o_username OUT USERS.USERNAME%TYPE
)

IS
BEGIN

  SELECT USERNAME
  INTO o_username
  FROM USERS WHERE username1 = o_username;

END;

当我试着打电话时:

DECLARE
   o_username USERS.USERNAME%TYPE;
BEGIN

   CHECKDUPLICATE('Jacklin', o_username);

   DBMS_OUTPUT.PUT_LINE('username :  ' || o_username);

END;

我收到错误消息:

Error starting at line 1 in command:
DECLARE
   o_username USERS.USERNAME%TYPE;
BEGIN

   CHECKDUPLICATE(Jacklin, o_username);

   DBMS_OUTPUT.PUT_LINE('username :  ' || o_username);

END;
Error report:
ORA-06550: line 5, column 19:
PLS-00201: identifier 'JACKLIN' must be declared
ORA-06550: line 5, column 4:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.
*Action:

“标识符'杰克林'必须声明是什么意思?(表名为USERS,列名称为USERNAME)。任何帮助都将受到赞赏。

编辑**我把Jacklin放在引号中,现在我收到了这条消息:

Error report:
ORA-01403: no data found
ORA-06512: at "L13JAV04.CHECKDUPLICATE", line 9
ORA-06512: at line 6
01403. 00000 -  "no data found"
*Cause:    
*Action:

尽管Jacklin确实存在于数据库中!

3 个答案:

答案 0 :(得分:3)

一旦引用“Jacklin”以使其被视为字符串文字而不是标识符,则您的SQL语句看起来不正确。

  SELECT USERNAME
  INTO o_username
  FROM USERS 
  WHERE username1 = o_username;

我的赌注是你要在WHERE子句中使用输入参数,而不是输出参数。

  SELECT USERNAME
  INTO o_username
  FROM USERS 
  WHERE username1 = username;

如果没有做任何初始化输出参数的值,检查输出参数的值是没有意义的。

但是你的代码似乎仍然没有意义。如果返回除1行以外的任何内容,SELECT INTO将抛出错误。如果您的查询返回0行,您将获得NO_DATA_FOUND异常。如果您的查询返回的行数超过1行,则会出现TOO_MANY_ROWS异常。您的过程名为CheckDuplicate,因此我猜测它的目的是检查表中是否已存在特定用户名,而不是尝试插入它并捕获唯一约束违规错误。如果这是您的代码的意图

  • 您可能希望它是一个功能
  • 您可能不想退回username
  • 您可能想要返回用户名是否已存在的指标

因此,我的猜测是你需要像

这样的东西
create or replace function isAvailable( p_username IN USERS.USERNAME%TYPE )
  return Boolean
is
  l_username USERS.USERNAME%TYPE;
begin
  select username
    into l_username
    from users
   where username = p_username;
  return false;
exception
  when no_data_found
  then
    return true;
end;

答案 1 :(得分:1)

您需要将Jacklin放在引号内,以便将其视为字符串。否则,解析器认为它是字段名称。

答案 2 :(得分:0)

没有用户名称“Jacklin”这就是为什么它会给你错误。请在最后添加例外

WHEN NO_DATA_FOUND 
THEN
......