错误 - ORA-06502: PL/SQL: 数字或值错误
Error - ORA-06502: PL/SQL: numeric or value error
我正在学习PL/SQL。我已经使用光标和嵌套 table 编写了下面的程序来显示员工姓名。
create or replace procedure
employees_data
is
cursor c1 is select * from employees;
type empl_tbl is table of c1%rowtype;
emp_data empl_tbl;
begin
open c1;
LOOP
fetch c1 bulk collect into emp_data limit 100;
exit when sql%notfound;
for i in 1..emp_data.last
loop
dbms_output.put_line ('employee name is : ' || to_char(emp_data(i).first_name));
end loop;
end loop;
close c1;
end employees_data;
它编译没有任何错误。当我执行程序时,我能够显示所有员工的姓名。但是,在显示数据之前会抛出以下错误。谁能帮我解决这个问题?
Error starting at line : 1 in command -
exec employees_data()
Error report -
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "HR.EMPLOYEES_DATA", line 12
ORA-06512: at line 1
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
提前致谢。
您的输出表明您尚未启用 DBMS_OUTPUT。使用 set serveroutput on
很明显,一旦处理完所有员工(我在显示中添加了行数)就会抛出错误:
#100:employee name is : Douglas
#1:employee name is : Jennifer
#2:employee name is : Michael
#3:employee name is : Pat
#4:employee name is : Susan
#5:employee name is : Hermann
#6:employee name is : Shelley
#7:employee name is : William
BEGIN employees_data; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "HR.EMPLOYEES_DATA", line 12
ORA-06512: at line 1
SQL>
那么,为什么会这样?这是因为您在 FETCH 之后使用了错误的测试。 SQL%NOTFOUND
是对 PL/SQL 中嵌入的 SQL 语句的测试。来自显式游标的 FETCH 不是 SQL 操作。
SQL%NOTFOUND
在 FETCH 之后永远不会为真,这意味着永远不会满足 EXIT WHEN 条件。因此,程序在获取所有记录后继续循环。程序抛出 ORA-06502
因为 emp_data.last
在获取所有记录后为 null,因此 LOOP 测试失败。
最佳解决方案是测试返回到数组中的行数:
fetch c1 bulk collect into emp_data limit 100;
exit when emp_data.count()=0;
通过这一更改,您的程序将 运行:
#100:employee name is : Douglas
#1:employee name is : Jennifer
#2:employee name is : Michael
#3:employee name is : Pat
#4:employee name is : Susan
#5:employee name is : Hermann
#6:employee name is : Shelley
#7:employee name is : William
PL/SQL procedure successfully completed.
SQL>
请注意,您不应使用 exit when c1%notfound;
。虽然这是测试 Explicit Cursor returns 是否为结果的正确语法,但它的行为与批量操作不同(并且不直观)。然后,只有当 FETCH returns LIMIT 子句中指定的确切行数 时,测试才成立。在您的场景中,这意味着您丢失了最后七条记录:
#98employee name is : Kevin
#99employee name is : Donald
#100employee name is : Douglas
PL/SQL procedure successfully completed.
SQL>
顺便说一句,转换 FIRST_DATE 是不必要的,因为(假设您使用的是标准 HR 模式)它已经是一个字符串。我们需要使用 to_char()
来表示数字或日期之类的东西,这样我们就可以控制格式。
我正在学习PL/SQL。我已经使用光标和嵌套 table 编写了下面的程序来显示员工姓名。
create or replace procedure
employees_data
is
cursor c1 is select * from employees;
type empl_tbl is table of c1%rowtype;
emp_data empl_tbl;
begin
open c1;
LOOP
fetch c1 bulk collect into emp_data limit 100;
exit when sql%notfound;
for i in 1..emp_data.last
loop
dbms_output.put_line ('employee name is : ' || to_char(emp_data(i).first_name));
end loop;
end loop;
close c1;
end employees_data;
它编译没有任何错误。当我执行程序时,我能够显示所有员工的姓名。但是,在显示数据之前会抛出以下错误。谁能帮我解决这个问题?
Error starting at line : 1 in command -
exec employees_data()
Error report -
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "HR.EMPLOYEES_DATA", line 12
ORA-06512: at line 1
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
提前致谢。
您的输出表明您尚未启用 DBMS_OUTPUT。使用 set serveroutput on
很明显,一旦处理完所有员工(我在显示中添加了行数)就会抛出错误:
#100:employee name is : Douglas
#1:employee name is : Jennifer
#2:employee name is : Michael
#3:employee name is : Pat
#4:employee name is : Susan
#5:employee name is : Hermann
#6:employee name is : Shelley
#7:employee name is : William
BEGIN employees_data; END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at "HR.EMPLOYEES_DATA", line 12
ORA-06512: at line 1
SQL>
那么,为什么会这样?这是因为您在 FETCH 之后使用了错误的测试。 SQL%NOTFOUND
是对 PL/SQL 中嵌入的 SQL 语句的测试。来自显式游标的 FETCH 不是 SQL 操作。
SQL%NOTFOUND
在 FETCH 之后永远不会为真,这意味着永远不会满足 EXIT WHEN 条件。因此,程序在获取所有记录后继续循环。程序抛出 ORA-06502
因为 emp_data.last
在获取所有记录后为 null,因此 LOOP 测试失败。
最佳解决方案是测试返回到数组中的行数:
fetch c1 bulk collect into emp_data limit 100;
exit when emp_data.count()=0;
通过这一更改,您的程序将 运行:
#100:employee name is : Douglas
#1:employee name is : Jennifer
#2:employee name is : Michael
#3:employee name is : Pat
#4:employee name is : Susan
#5:employee name is : Hermann
#6:employee name is : Shelley
#7:employee name is : William
PL/SQL procedure successfully completed.
SQL>
请注意,您不应使用 exit when c1%notfound;
。虽然这是测试 Explicit Cursor returns 是否为结果的正确语法,但它的行为与批量操作不同(并且不直观)。然后,只有当 FETCH returns LIMIT 子句中指定的确切行数 时,测试才成立。在您的场景中,这意味着您丢失了最后七条记录:
#98employee name is : Kevin
#99employee name is : Donald
#100employee name is : Douglas
PL/SQL procedure successfully completed.
SQL>
顺便说一句,转换 FIRST_DATE 是不必要的,因为(假设您使用的是标准 HR 模式)它已经是一个字符串。我们需要使用 to_char()
来表示数字或日期之类的东西,这样我们就可以控制格式。