【问题标题】:Why does this basic 'Select Into' stored procedure not work?为什么这个基本的“选择进入”存储过程不起作用?
【发布时间】:2013-08-01 05:22:57
【问题描述】:

我正在运行 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:

“必须声明标识符'Jacklin'是什么意思?(表称为USERS,列名称为USERNAME)。任何帮助将不胜感激。

编辑** 我把杰克林放在引号里,我现在收到这条消息:

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 确实存在于数据库中!

【问题讨论】:

  • 杰克林是一个字符串。应该用单引号括起来
  • 谢谢!但我现在收到另一条错误消息..错误报告:ORA-01403:未找到数据 ORA-06512:在“L13JAV04.CHECKDUPLICATE”,第 9 行 ORA-06512:在第 6 行 01403。00000 -“未找到数据” *原因:*行动:
  • 我把它编辑成我原来的问题以便于阅读
  • 您打算在 where 子句 FROM USERS WHERE username1 = o_username; 中做什么,您正在比较您的输入和输出参数?如果你有一个名为username1 的列名,那么你应该使用表别名

标签: sql oracle stored-procedures procedure declare


【解决方案1】:

一旦引用 '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;

【讨论】:

    【解决方案2】:

    您需要将 Jacklin 放在引号内才能将其视为字符串。否则解析器认为它是一个字段名。

    【讨论】:

    • 我这样做了,但我收到另一条错误消息(已编辑为原始问题)
    • 见贾法尔的评论。你的 where 子句是错误的。 FROM USERS WHERE username1 = o_username 应替换为 FROM USERS WHERE username1 = USERNAME_FIELD_IN_TABLE(无论是什么)。
    【解决方案3】:

    不会有名为“Jacklin”的用户,这就是它给你错误的原因。请在最后添加例外

    WHEN NO_DATA_FOUND 
    THEN
    ......
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-07
      • 1970-01-01
      • 1970-01-01
      • 2015-08-16
      • 2013-08-10
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      相关资源
      最近更新 更多