Вы почти все сделали нормально. Немногое относительно процедуры,
Запустите следующую команду (возможно, вы пропустили ошибку)
ALTER PROCEDURE student_grade COMPILE;
Warning: Procedure altered with compilation errors
вам не нужно делать параметр p_average
как IN OUT, OUT должно быть достаточно, поскольку вы вычисляете его внутри.
чтобы присвоить какое-то значение параметру OUT, вам не нужно использовать SET. Допускается только присваивание с использованием оператора присваивания. см. ниже
CREATE OR REPLACE PROCEDURE student_grade
(
p_school_no IN lessons.school_number%TYPE
,p_lesson OUT lessons.lesson_name%TYPE
,p_midterm_1 OUT lessons.midterm_notu_1%TYPE
,p_midterm_2 OUT lessons.midterm_notu_2%TYPE
,p_final OUT lessons.final_notu%TYPE
,p_average OUT NUMBER
) IS
BEGIN
SELECT d.lesson
,d.midterm_notu_1
,d.midterm_notu_2
,d.final_notu
INTO p_lesson
,p_midterm_1
,p_midterm_2
,p_final
FROM lessons d
WHERE d.shool_number = p_school_no;
--assign to the output variable for average
p_average := (((d.midterm_notu_1 * 25) / 100) + ((d.midterm_notu_2 * 30) / 100) + ((d.final_notu * 45) / 100));
END;
/
Я считаю, что из-за ошибки в процедуре, которую вы не смогли протестировать, после внесения вышеуказанных изменений она должна работать.
Вы также можете протестировать ее с помощью анонимного блока PL / SQL вместо SQL командное окно, которое было бы проще. Например,
DECLARE
--assign the input directly here in the declare section
v_school_no lessons.school_number%type := 10;
v_lesson lessons.lesson_name%type;
v_midterm_1 lessons.midterm_notu_1%type;
v_midterm_2 lessons.midterm_notu_2%type;
v_final lessons.final_notu%type;
v_average NUMBER;
BEGIN
-- call the procedure
student_grade(
v_lesson,
v_midterm_1,
v_midterm_2 ,
v_final,
v_average );
DBMS_OUTPUT.put_line ('Student Grade');
DBMS_OUTPUT.put_line ('School Number: ' ||v_school_no);
DBMS_OUTPUT.put_line ('Midterm 1: ' || v_midterm_1);
DBMS_OUTPUT.put_line ('Midterm 2: ' || v_midterm_2 );
DBMS_OUTPUT.put_line ('Final: ' || v_final);
DBMS_OUTPUT.put_line ('Average: ' || v_average );
END;
/
Сообщите мне, решит ли это вашу проблему;
ПЕРЕСМОТРЕННЫЙ ОТВЕТ С СПЕЦИФИКАМИ C ПРОБЛЕМА С ИСПОЛЬЗОВАНИЕМ И ИСПОЛЬЗОВАНИЕМ ИНСТРУМЕНТА
Я настоятельно рекомендую / предлагаю вам изучить документацию PL / SQL перед переходом к следующему заданию. Это поможет вам понять возникающие ошибки и исправить их. Также есть много видеороликов об инструменте SQL Developer, как их эффективно использовать. Проверьте и их.
Возвращаясь к вам, проблема, которую я пробовал на своей машине, и есть много проблем со сценарием, которые я приходилось исправлять одно за другим, просматривая сообщения об ошибках. Найдите пункты и окончательное решение, которое должно сработать, иначе все будет готово.
Проблемы: названия столбцов в таблице отличаются от написанного вами кода
WHERE d.shool_number = p_school_no;
-> shool_number не является существующим столбцом, вероятно, это d.school_number
v_lesson lessons.lesson_name%type;
-> фактический столбец lesson
, а не lesson_name
. Я могу сказать это из вашего предложения select в процедуре p_lesson OUT lessons.lesson_name%type,
-> то же, что и в пункте 2 p_average := (((d.midterm_notu_1 * 25)/100) + ((d.midterm_notu_2 * 30)/100) + ((d.final_notu * 45)/100));
- вы не можете ссылаться на такие столбцы, что это означает с "d."
где код не знает, к чему он относится. d
вы использовали в запросе выбора как псевдоним таблицы lessons
, и с помощью оператора select заканчивается область действия d
. Поскольку вы уже ввели значения в выходные переменные, такие как p_midterm_1, p_midterm_2, p_final
, используйте их вместо . - Кроме того, убедитесь, что оператор select возвращает только одну строку на
school_number=20201754
, иначе вы закончите с ошибкой ORA-01422: exact fetch returns more than requested number of rows
и тогда есть другие способы справиться с этим. (на данный момент я ничего не скажу по этому поводу) - Последняя точка, в которой вы пытаетесь протестировать процедуру вроде
student_grade( v_lesson, v_midterm_1, v_midterm_2 , v_final, v_average );
-> вы передаете неправильное количество аргументов в процедуру, не включая v_school_no
в качестве первого параметра.
Однако я создал свою собственную настройку и соответствующим образом изменил процедуру и тест, см. Ниже.
--table definition
create table lessons (school_number number,lesson varchar2(100),midterm_notu_1 number,midterm_notu_2 number,final_notu number);
--inserting unique rows per school_number
insert into lessons values(20201754,'Maths',35,55,85);
insert into lessons values(20201755,'Science',45,65,95);
-- to enable the dbms_output
SET SERVEROUTPUT ON;
--procedure definition
CREATE OR REPLACE PROCEDURE student_grade(
p_school_no IN lessons.school_number%type,
p_lesson OUT lessons.lesson%type,
p_midterm_1 OUT lessons.midterm_notu_1%type,
p_midterm_2 OUT lessons.midterm_notu_2%type,
p_final OUT lessons.final_notu%type,
p_average OUT NUMBER
)
IS
BEGIN
SELECT
d.lesson,
d.midterm_notu_1,
d.midterm_notu_2,
d.final_notu
INTO
p_lesson,
p_midterm_1,
p_midterm_2,
p_final
FROM lessons d
WHERE d.school_number = p_school_no;
p_average := (((p_midterm_1 * 25)/100) + ((p_midterm_2 * 30)/100) + ((p_final * 45)/100));
END student_grade;
/
--testing the procedure
DECLARE
v_school_no lessons.school_number%type := 20201754;
v_lesson lessons.lesson%type;
v_midterm_1 lessons.midterm_notu_1%type;
v_midterm_2 lessons.midterm_notu_2%type;
v_final lessons.final_notu%type;
v_average NUMBER;
BEGIN
student_grade(
v_school_no,
v_lesson,
v_midterm_1,
v_midterm_2 ,
v_final,
v_average );
DBMS_OUTPUT.put_line ('Student Grade');
DBMS_OUTPUT.put_line ('School Number: ' ||v_school_no);
DBMS_OUTPUT.put_line ('Midterm 1: ' || v_midterm_1);
DBMS_OUTPUT.put_line ('Midterm 2: ' || v_midterm_2 );
DBMS_OUTPUT.put_line ('Final: ' || v_final);
DBMS_OUTPUT.put_line ('Average: ' || v_average );
END;
/