Почему эта базовая хранимая процедура «Выбрать в» не работает?

Я запускаю разработчика 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:

Несмотря на то, что Джеклин существует в базе данных!


person DeaIss    schedule 31.07.2013    source источник
comment
Джеклин — это струна. Должен быть заключен в одинарные кавычки   -  person Noel    schedule 31.07.2013
comment
Спасибо! Но теперь я получаю другое сообщение об ошибке. Отчет об ошибке: ORA-01403: данные не найдены ORA-06512: в L13JAV04.CHECKDUPLICATE, строка 9 ORA-06512: в строке 6 01403. 00000 - данные не найдены * Причина: * Действие:   -  person DeaIss    schedule 31.07.2013
comment
Я отредактировал его в своем исходном вопросе для облегчения чтения   -  person DeaIss    schedule 31.07.2013
comment
что вы собираетесь делать в своем предложении where FROM USERS WHERE username1 = o_username; вы сравниваете параметры ввода и вывода? если у вас есть имя столбца с именем username1, вы должны использовать псевдоним таблицы   -  person Jafar Kofahi    schedule 31.07.2013


Ответы (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;

Нет смысла проверять значение выходного параметра, если вы ничего не сделали для его инициализации.

Но ваш код по-прежнему не имеет смысла. SELECT INTO выдаст ошибку, если будет возвращено что-либо, кроме 1 строки. Если ваш запрос возвращает 0 строк, вы получите исключение NO_DATA_FOUND. Если ваш запрос возвращает более одной строки, вы получите исключение 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;
person Justin Cave    schedule 31.07.2013

Вам нужно поместить Jacklin в кавычки, чтобы он рассматривался как строка. В противном случае синтаксический анализатор считает, что это имя поля.

person Barbara Laird    schedule 31.07.2013
comment
Я сделал это, но получаю другое сообщение об ошибке (отредактировано в исходный вопрос) - person DeaIss; 31.07.2013
comment
См. комментарий Джафара. Ваше предложение where неверно. FROM USERS WHERE username1 = o_username следует заменить на FROM USERS WHERE username1 = USERNAME_FIELD_IN_TABLE (что бы это ни было). - person Barbara Laird; 31.07.2013

Не было бы пользователя по имени «Jacklin», поэтому он выдает вам ошибку. Пожалуйста, добавьте исключение в конце

WHEN NO_DATA_FOUND 
THEN
......
person Harshit    schedule 31.07.2013