#oracle #plsql #oracle10g
#Oracle #plsql #oracle10g
Вопрос:
Я только изучаю plsql, и у меня возникают проблемы с выполнением простых SQL-запросов в процедурах. Я хотел написать процедуру, которая отображает все записи из таблицы.
create or replace procedure display_all_students
as
begin
dbms_output.put_line('Listing all the student records');
select * from student;
end;
Я получаю это в результате :
Предупреждение: Процедура создана с ошибками компиляции.
Чего мне не хватает, насколько я понимаю, так это того, что plsql является расширением sql, есть ли какой-то другой способ добиться этого вместо этого?
Обновленный код, я все еще сталкиваюсь с той же проблемой. Есть ли способ, с помощью которого мы можем отлаживать эти ошибки одну за другой?
-- procedure to display the table
create or replace procedure display_all_students
as
-- declarations
cursor cur_student is
select * from student;
student_record student%rowtype;
begin
dbms_output.put_line('Listing all the student records');
for student_record in cur_student
loop
dbms_output.put_line(student_record);
end loop;
end;
Комментарии:
1. ПРИМЕЧАНИЕ: Если вы компилируете в SQL * Plus, вы можете использовать команду
show errors
, чтобы увидеть, каковы фактические ошибки компиляции после предупреждения
Ответ №1:
Вы не можете просто select * from student;
. Это ничего не значит, что это делает с возвращенными данными?
Вместо этого вам нужно либо создать курсор, который selects ... from student
или SELECT columns INTO variables FROM student;
.
Итак, для вашей проблемы вам нужно создать курсор, который выбирает из student, а затем перебирает его и выводит каждую строку. Например:
create or replace procedure display_all_students
as
CURSOR cur_student IS
SELECT student_id, first_name, last_name FROM student;
begin
dbms_output.put_line('Listing all the student records');
FOR rec IN cur_student
LOOP
dbms_output.put_line( 'ID[' || rec.student_id || '] Name: '
|| rec.first_name || ' ' rec.last_name);
END LOOP;
end;
То же самое, что написано длинным путем, вероятно, лучше изучать как новичку, поскольку оно учит вас различным аспектам курсоров и т. Д. Это тот же код, написанный длинным путем.
create or replace procedure display_all_students
as
CURSOR cur_student IS
SELECT student_id, first_name, last_name FROM student;
-- Host Variable to store cursor result.
rec cur_student%ROWTYPE;
begin
dbms_output.put_line('Listing all the student records');
OPEN cur_student;
LOOP
FETCH cur_student INTO rec;
EXIT WHEN cur_student%NOTFOUND;
dbms_output.put_line( 'ID[' || rec.student_id || '] Name: '
|| rec.first_name || ' ' rec.last_name);
END LOOP;
CLOSE cur_student;
end;
FOR variable IN cursor
Синтаксис позаботится о некоторых вещах для вас:
- Вам не нужно декализировать переменную Host
- Вам не нужно ОТКРЫВАТЬ курсор
- Вам не нужно проверять, когда вы достигли конца данных
- Вам не нужно закрывать курсор
Разница только в синтаксисе. Фактическое выполнение и производительность обоих практически идентичны.
Комментарии:
1. Добавлен мой измененный код, нужно ли вручную выбирать все атрибуты?
2. Я думаю, вы можете ВЫБРАТЬ * и использовать запись (но я не уверен на 100%). Но вы не можете DBMS_OUTPUT запись, вы можете только DBMS_OUTPUT текст (а также числа и даты, которые неявно преобразуются в текст по умолчанию
TO_CHAR
)3. Отлично, большое спасибо за это. Еще одна вещь, можно ли как-то получить больше информации об ошибке компиляции?
4. Как указано выше, используйте
show errors
в SQL *Plus . Если вы используете инструмент с графическим интерфейсом, такой как TOAD, я не могу вам помочь, извините. Вся моя работа над putty, так что я ботаник командной строки
Ответ №2:
Имейте в виду, что ваш PLSQL запущен на сервере; dbms_output не выводит текст на ваш экран, он сбрасывает его в таблицу на сервере, которую, как знает ваш клиент, он должен просматривать после возврата управления. Просто select сам по себе извлек бы данные обратно, и их некуда было бы поместить (концептуально), и поэтому компилятор жалуется.
Обычно вы хотели бы что-то сделать с данными — сохранить их где-нибудь, выполнить итерацию по ним, использовать для обновления чего-то еще и т.д..
например:
---
for i in (select * from student)
loop
dbms_output.put_line(i.name);
end loop;
---