#sql #oracle
#sql #Oracle
Вопрос:
Я пытаюсь запустить приведенный ниже код, но он выдает ошибку. Я новичок в ORACLE, и любая помощь приветствуется, также какие дополнения можно внести в код, чтобы гарантировать, что эта ошибка будет зафиксирована в будущем, и пользователю будет предоставлено значимое сообщение спасибо.
DECLARE
V_lname VARCHAR2(15);
BEGIN
SELECT last_name INTO v_lname
FROM employees
WHERE first_name='John';
DBMS_OUTPUT.PUT_LINE ('John' 's last name is : '
|| v_lname);
END;
и у меня эта ошибка;
Отчет об ошибке ORA-01422: точная выборка возвращает больше запрошенного количества строк ORA-06512: в строке 4
Ответ №1:
Сообщение об ошибке понятно, вы можете получить только одно значение в свою v_lname
переменную, поэтому PL / SQL выдает ошибку, сообщающую, что ваш запрос пытается вернуть несколько строк.
Либо:
- Измените запрос, чтобы он возвращал только одну строку
- Измените PL / SQL так, чтобы он мог обрабатывать несколько строк.
Я продемонстрирую второй вариант, поскольку я понятия не имею, какой сотрудник с именем «Джон» вам может понадобиться.
begin
for rJohn in
(select last_name
from employees
where first_name='John'
) loop
dbms_output.put_line ('John''s last name could be : '|| rJohn.last_name);
end loop;
end;
/
Здесь я использую неявный курсор для цикла (https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/cursor-FOR-LOOP-statement.html#GUID-62C9A3C8-82F9-468F-8D84-81672E67736D ) для выполнения dbms_output.put_line
вызова по каждой строке, которую он находит для вашего запроса.
Ответ №2:
Два бесполезных варианта. Почему бесполезно? Потому что вам, вероятно, следует переписать запрос так, чтобы он возвращал только желаемое «John».
Кроме того, предложение: пусть переменная ссылается на тип данных столбца, не исправляйте его, например varchar2(15)
. Что, если вам — когда-нибудь в будущем — придется изменить таблицу и увеличить столбец до varchar2(25)
? Ваш код с треском провалится.
Первый вариант: использовать агрегатную функцию, такую как MIN
или MAX
:
DECLARE
V_lname employees.last_name%type; --> this
BEGIN
SELECT MAX(last_name) --> this
INTO v_lname
FROM employees
WHERE first_name = 'John';
DBMS_OUTPUT.PUT_LINE ('John' 's last name is : ' || v_lname);
END;
Другой вариант — использовать ROWNUM
:
DECLARE
V_lname employees.last_name%type; --> this
BEGIN
SELECT last_name
INTO v_lname
FROM employees
WHERE first_name = 'John'
AND rownum = 1; --> this
DBMS_OUTPUT.PUT_LINE ('John' 's last name is : ' || v_lname);
END;