如何解决 PL/SQL: Statement ignored 错误?

How can I solve PL/SQL: Statement ignored error?

我正在尝试编写一个程序。该程序将使用 school number 和 course_name、midterm_not、final_not 进行查询,将显示平均分,但期中和期末成绩将以百分比计算。 60岁以下就结束了,就pass了。

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

'accept'(接受 p_school_no 提示)是一个 sqlplus 指令,而不是 pl/sql 语句。 PL/SQL 完全在数据库内部运行,无法从用户那里获得 'accepting' 输入。 'accepting' run-time 值的唯一方法是在调用过程时在命令行上提供。这就是那些 IN 参数的用途。

exec student_grade('schoolname');

此外,'set' (SET p_average := ) 对 SELECT 无效。它属于更新。

你几乎完成了一切。关于程序的一些事情,

运行 下面的命令(可能是你看错了部分)

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 命令 window 来测试它,这样会更容易。 例如

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

如果它解决了您的问题,请告诉我;


针对使用和工具使用的特定问题修改后的答案

我强烈建议 recommend/suggests 你在继续下一个作业之前先查看 PL/SQL 的文档。它将帮助您了解您遇到的错误,以便您可以更正它。 SQL Developer 工具上也有很多视频,如何使用它们 efficiently.Check 它们也是。

回到你的问题 我已经在我的机器上试过了,脚本有很多问题,我必须通过查看错误消息来一一解决。请找到应该起作用的要点和最终解决方案,否则我就完成了。

问题:table中的列名称与您编写的代码

存在差异
  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 您在 select 查询中使用了 table lessons 的别名,并且 select 语句结束了 d 的范围本身. 因为您已经将值取到输出变量,例如 p_midterm_1, p_midterm_2, p_final,所以请改用它们
  5. 另外确保 select 语句 returns 每个 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;
/