Ошибка компиляции при создании элементарной процедуры plsql

#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;
---