Поскольку вы используете PL / SQL Developer , убедитесь, что вы пишете свой код в окне процедуры. Тогда ошибка компиляции будет четко выделена. В данном случае это пропущенная точка с запятой в конце оператора select into
.
Или в SQL* Plus вы можете использовать show errors
:
Warning: Procedure created with compilation errors.
SQL> show errors
Errors for PROCEDURE AVG_GRADES:
LINE/COL ERROR
-------- -----------------------------------------------------------------
6/1 PL/SQL: SQL Statement ignored
9/12 PL/SQL: ORA-00933: SQL command not properly ended
или полный синтаксис , show errors procedure avg_grades
.
Или вы можете напрямую запросить dba|all|cdb|user_errors
:
select * from user_errors e
where e.name = 'AVG_GRADES'
and e.attribute = 'ERROR';
Кроме того, определение таблицы можно записать более кратко:
create table enrolledinclasses
( st_id primary key constraint fk_stid references student(st_id)
, c_id constraint fk_coid references course (c_id)
, grade number(2) constraint checkgrade check (grade>-1)
);
student.st_id
и course.c_id
, вероятно, должны быть числами или целыми числами или, по крайней мере, varchar2
, а не char
.
Хорошей практикой является использование отступа кода для выравнивания кода в блоки, показывающие их структуру зависимостей. Это может дать что-то вроде этого:
create or replace procedure avg_grades as
avg_grades number := 0;
begin
select avg(grade) into avg_grades
from enrolledinclasses;
dbms_output.put_line('The average grade is: ' || avg_grades);
exception
when no_data_found then
dbms_output.put_line('No Data Is Found.');
end;
Возможно, вы захотите round()
это среднее значение перед отображением, так как по умолчанию оно может отображаться с гораздо большим количеством десятичных знаков, чем вы могли бы хотеть.
Кроме того, невозможно получить исключение no_data_found
из агрегированного запроса для одной группы, подобного этому. Если в таблице нет строк, в результате вы получите нулевое значение, а не ошибку.