如何解决pl/sql:statement-ignored错误?

6gpjuf90  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(1194)

我在写一个程序。将使用 school number 课程名称、期中成绩、期末成绩、平均成绩将以%计算。如果不到60岁,就结束了,就通过了。

set serveroutput on;
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
    p_average := (((d.midterm_notu_1 * 25)/100) + ((d.midterm_notu_2 * 30)/100) + ((d.final_notu * 45)/100));
    END;

    DECLARE
    v_school_no lessons.school_number%type := 20201754;
    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
    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;

我做了这样的事情,当我运行程序,它说 "Procedure student_grade compiled" 但是当我试着管理 DECLARE 第二部分给出了这样一个错误;

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 := 有人能帮我解决这些问题吗?

sh7euo9m

sh7euo9m1#

你几乎做得很好。关于程序的一些事情,
运行下面的命令(可能是您在零件上查找错误)

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

让我知道它是否解决了你的问题;

修改后的答案与具体问题的使用和工具的使用

我强烈建议/建议您在继续下一个任务之前查看pl/sql的文档。它将帮助你理解错误,这样你就可以纠正它。还有很多关于SQLDeveloper工具的视频,如何有效地使用它们。请检查它们。
回到你的问题,我已经尝试在我的机器和有许多问题的脚本,我不得不修复一个又一个查看错误消息。请找出要点和最终的解决办法,应该工作,否则我就完了。
问题:表中列的名称与您编写的代码不同 WHERE d.shool_number = p_school_no; -->学号不是现有列,应该是
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 您已在select查询中使用作为表的别名 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;
/
lvmkulzt

lvmkulzt2#

“accept”(accept p\u school\u no prompt)是一个sqlplus指令,而不是pl/sql语句。pl/sql完全在数据库中运行,无法“接受”用户的输入。“接受”运行时值的唯一方法是在调用过程时在命令行上提供。这就是那些参数的作用。

exec student_grade('schoolname');

另外,'set'(set p\u average:=)对于select无效。它属于更新。

相关问题