如何解决 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中的列名称与您编写的代码
存在差异
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
您在 select 查询中使用了 table lessons
的别名,并且 select 语句结束了 d
的范围本身. 因为您已经将值取到输出变量,例如 p_midterm_1, p_midterm_2, p_final
,所以请改用它们。
- 另外确保 select 语句 returns 每个
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;
/
我正在尝试编写一个程序。该程序将使用 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中的列名称与您编写的代码
存在差异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
您在 select 查询中使用了 tablelessons
的别名,并且 select 语句结束了d
的范围本身. 因为您已经将值取到输出变量,例如p_midterm_1, p_midterm_2, p_final
,所以请改用它们。- 另外确保 select 语句 returns 每个
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;
/