Ошибка при создании процедуры: ORA-01744: неподходящее INTO
Есть две таблицы. Первая EQUI (Оборудование):
Вторая таблица REST (Рестораны):
Мне необходимо написать процедуру поиска ресторана с минимальной стоимостью оборудования.
Я написал следующее:
create or replace PROCEDURE min_rest
IS minprice NUMBER(10,2);
BEGIN
select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
from rest r, equi e
where
r.equi_id = e.eid
and
e.eprice = (SELECT MIN(eprice) into minprice FROM equi);
END;
Но получаю ошибку:
LINE/COL ERROR
--------- -------------------------------------------------------------
4/5 PL/SQL: SQL Statement ignored
9/40 PL/SQL: ORA-01744: неподходящее INTO
Errors: check compiler log
Может кто-то подскажет, в чем у меня ошибка?
Причем, если я пишу просто SQL запрос, то все работает:
select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
from rest r, equi e
where
r.equi_id = e.eid
and
e.eprice = (SELECT MIN(eprice) FROM equi);
Ответы (2 шт):
SELECT INTO это отдельный вид запроса. INTO нельзя использовать в подзапросе, можно только в запросе верхнего уровня. Поэтому и возникает ошибка.
Впрочем, это не единственная проблема в процедуре:
Вообще непонятно зачем выбирать
minpriceв переменную. Переменная нигде не используется в дальнейшем. Проще написать подзапрос также как в SQL.Запрос
SELECTпосреди процедуры сам по себе ничего не делает. :a. Если нужно вернуть данные по ресторану в отдельных переменных, то нужно объявить аргументы процедуры (
p_rid,p_rnameи т.д.), записывать данные в них с помощьюSELECT INTO.б. Если нужно вернуть список минимальных ресторанов, то почитайте как вернуть из процедуры курсор в Oracle.
в. Если нужно распечатать данные о ресторане(-ах), то почитайте как пользоваться пакетом
dbms_output. В любом случае потребуется использовать один из способов а) или б).
Из комментариев: Вызываться без каких либо параметров, она должна просто осуществлять поиск ресторана с минимальной стоимостью оборудования и выводить его. ВСЁ!!!!!!!!!!! (ノಠ益ಠ)ノ彡┻━┻
«Выводить» я понял, как выводить в выходной поток БД. Вполне может быть что имеется ввиду что-то другое, например то, что у процедуры будут OUT параметры, через которые будут возвращены данные.
Примерно так будет работать с курсором:
create or replace procedure min_rest is
begin
--Ресторанов с минимальной ценой может быть несколько
for r in (select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
from rest r, equi e
where r.equi_id = e.eid
and e.eprice = (SELECT MIN(eprice) FROM equi)) loop
--Выводим каждый
dbms_output.put_line(r.rid || ', ' || r.rname || ', ' || r.rcity || ', ' ||
r.rplaces || ', ' || r.eprice);
end loop;
end min_rest;
А так с отдельными переменными:
create or replace procedure min_rest is
v_rid rest.rid%type;
v_rname rest.rname%type;
v_rcity rest.rcity%type;
v_rplaces rest.rplaces%type;
v_eprice rest.eprice%type;
begin
--Если ресторанов с минимальной ценой будет несколько,
--то произойдет ошибка
select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
--заполняем переменные
into v_rid, v_rname, v_rcity, v_rplaces, v_eprice
from rest r, equi e
where r.equi_id = e.eid
and e.eprice = (SELECT MIN(eprice) FROM equi);
--выводим переменные
dbms_output.put_line(v_rid || ', ' || v_rname || ', ' || v_rcity || ', ' ||
v_rplaces || ', ' || v_eprice);
end min_rest;
О причине ошибки с путями её обхода уже подробно написано в ранее данном ответе.
Вызываться без каких либо параметров, она должна просто осуществлять поиск ресторана с минимальной стоимостью оборудования и выводить его. ВСЁ!
Это можно довольно просто сделать, вернув открытый курсор неявно:
create or replace procedure min_rest is
rc sys_refcursor;
begin
open rc for
select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
from rest r
join equi e on e.eid = r.equi_id
where e.eprice = (select min (eprice) from equi);
dbms_sql.return_result (rc);
end min_rest;
/
exec min_rest
ResultSet #1
[Тут будет вывод результата работы процедуры]
Если неявный возврат результата нежелателен, или версия БД старше 12c, то тот же самый результат можно вернуть явно с одним параметром вывода (или преобразовав в функцию):
create or replace procedure min_rest (rc out sys_refcursor) is
begin
open rc for
select r.rid, r.rname, r.rcity, r.rplaces, e.eprice
from rest r
join equi e on e.eid = r.equi_id
where e.eprice = (select min (eprice) from equi);
end min_rest;
/
var rc refcursor
exec min_rest (:rc)
print rc
Заметка об ограничении ответственности: так как структура таблиц и данные в вопросе приведены картинками, не представляется возможным проверить на отсутствие ошибок.




