Как я могу решить ошибку PL / SQL: Statement ignored? - PullRequest
1 голос
/ 04 августа 2020

Я новичок в PL / SQL и пытаюсь написать процедуру. Будет запрошена процедура с номером школы и курсом, midterm_not, final_not, будет показано среднее значение, но промежуточные и итоговые оценки будут рассчитаны в%. Если он меньше 60, он будет закончен, и он будет принят. часть выдает такую ​​ошибку;

Error report -
ORA-06550: line 9, column 5:
PLS-00905: SYSTEM.STUDENT_GRADE object is invalid
ORA-06550: line 9, column 5:
PL/SQL: Statement ignored
06550. 00000 -  "line %s, column %s:\n%s"
*Cause:    Usually a PL/SQL compilation error.

У него проблема в p_average: = Может ли кто-нибудь помочь мне с этими проблемами?

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Вы почти все сделали нормально. Немногое относительно процедуры,

Запустите следующую команду (возможно, вы пропустили ошибку)

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, как их эффективно использовать. Проверьте и их.

Возвращаясь к вам, проблема, которую я пробовал на своей машине, и есть много проблем со сценарием, которые я приходилось исправлять одно за другим, просматривая сообщения об ошибках. Найдите пункты и окончательное решение, которое должно сработать, иначе все будет готово.

Проблемы: названия столбцов в таблице отличаются от написанного вами кода

  1. WHERE d.shool_number = p_school_no; -> shool_number не является существующим столбцом, вероятно, это d.school_number
  2. v_lesson lessons.lesson_name%type; -> фактический столбец lesson, а не lesson_name. Я могу сказать это из вашего предложения select в процедуре
  3. p_lesson OUT lessons.lesson_name%type, -> то же, что и в пункте 2
  4. 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, используйте их вместо .
  5. Кроме того, убедитесь, что оператор select возвращает только одну строку на school_number=20201754, иначе вы закончите с ошибкой ORA-01422: exact fetch returns more than requested number of rows и тогда есть другие способы справиться с этим. (на данный момент я ничего не скажу по этому поводу)
  6. Последняя точка, в которой вы пытаетесь протестировать процедуру вроде 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;
/
0 голосов
/ 04 августа 2020

'accept' (приглашение accept p_school_no) - это директива sqlplus, а не инструкция pl / sql. PL / SQL полностью выполняется внутри базы данных и не имеет средств «принятия» ввода от пользователя. Единственный способ «принять» значения времени выполнения - указать их в командной строке при вызове процедуры. Вот для чего предназначены эти параметры IN.

exec student_grade('schoolname');

Кроме того, 'set' (SET p_average: =) недействителен для SELECT. Он принадлежит UPDATE.

...