Обнаружил символ «INTO» при ожидании одного из следующих - PullRequest
0 голосов
/ 03 января 2019

Я обнаружил следующую ошибку при определении функции.«Обнаружен символ« INTO »при ожидании одного из следующих действий: ...» Я пробую этот пример с веб-сайта.Я также хотел понять логику курсоров, используемую здесь.

  1. Можем ли мы извлечь значения и закрыть курсор в части определения?
  2. Каково значение c1% notfoundзаблокировать и присвоить p_cid высокое значение 9999?
create or replace function get_cust_id(p_cname IN varchar2)
RETURN number
IS
p_cid number;

cursor c1 is
select p_cid from customers where c_name = p_cname;

BEGIN

OPEN c1;
FETCH c1 INTO into p_cid;

if c1%notfound
then
p_cid:=9999;
end if;

close c1;

RETURN p_cid;

EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20001,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END;

===================================================

Вышеупомянутая проблема "INTO" была исправлена ​​из-за ошибки опечатки.

Я сейчас пытаюсь позвонитьфункция, но вывод не соответствует ожидаемому:

select c_name,get_cust_id(c_name) as cust_id
from customers
where city='London';

Вывод:

C_NAME  CUST_ID
Alice    - 
Patrick  - 

Ответы [ 2 ]

0 голосов
/ 03 января 2019

Вывод был таким, как ожидалось, когда я изменил следующую строку:

select c_id into p_cid from customers where c_name = p_cname;

Вывод:

C_NAME  CUST_ID
Alice   3
Patrick 6
0 голосов
/ 03 января 2019

Помимо двойного into, которое @Lukasz указал в комментариях, ваш запрос курсора делает следующее:

select p_cid from customers where c_name = p_cname;

p_cid - это только что объявленное вами число, которое не имеетбыло назначено значение еще.Таким образом, вы фактически делаете:

select null from customers where c_name = p_cname;

, поэтому ваш тестовый запрос получает нулевые значения от вызовов функций.Вам нужно изменить p_cid в этом запросе на имя столбца в таблице, которое, как я предполагаю, будет либо id, либо c_id:

create or replace function get_cust_id(p_cname IN varchar2)
RETURN number
IS
p_cid number;

cursor c1 is
select c_id from customers where c_name = p_cname;

BEGIN

OPEN c1;
FETCH c1 INTO p_cid;
...

Можем ли мы получить значенияот и закрыть курсор в части определения?

Нет.

Каково значение c1% не найденного блока и присвоения высокого значения 9999 для p_cid?

Если вы передадите имя, которое не существует (что не может произойти так, как вы его называете, но в любом случае оно очень надумано), тогда запрос курсора не найдет данных для этого имени.fetch не выдаст ошибку, но на самом деле ничего не получит. Атрибут курсора% notfound` имеет значение true, поскольку ни одна строка не была выбрана.

В этой ситуации if c1%notfound имеет значение true, поэтому выполняется оператор p_cid:=9999;, и это значение равнопозже возвращается к вызывающей стороне.

Фактически он возвращает 9999 как «магическое число», указывающее, что не было найдено действительного идентификатора.(Возможно, было бы безопаснее либо возвратить ноль, либо выдать исключение, если это произошло - магические числа могут вызвать проблемы позже, например, - вполне очевидно, - если у вас также есть реальный клиент с идентификатором 9999 ...)

Существуют более простые способы добиться того, что выполняет эта функция, но, вероятно, она пытается научить вас конкретным вещам в ее придуманном виде.

...