PL/SQL 异常
PL/SQL Exception
有没有办法将这个错误(ORA-06502:PL/SQL:数字或值错误:字符到数字转换错误)捕获到异常中?每当我使用字符串作为输入时,就会发生这种情况。我以为其他人的异常会抓住它,但它不会。
DECLARE
v_order_no NUMBER(10) := &Order_Number;
var NUMBER(10);
BEGIN
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
正确的例外是VALUE_ERROR
。但是,OTHERS
也应该捕获该错误。您的代码的问题是在块的声明部分中抛出了异常。如果您在 BEGIN
之后移动该分配,您应该能够捕获该异常。
DECLARE
v_order_no NUMBER(10);
var NUMBER(10);
BEGIN
v_order_no := &Order_Number;
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN VALUE_ERROR THEN
dbms_output.put_line('value_error');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
放置一个额外的 Begin
和 END
块应该可以解决您的问题并且应该捕获异常,但是 @pablomatico 建议的是编写块的正确方法。如果您想坚持使用自己的代码,您可以这样做:
BEGIN
DECLARE
v_order_no NUMBER(10) := &Order_Number;
var NUMBER(10);
BEGIN
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
END;
我会给分配它自己的子块,这样你就可以保证任何验证错误都来自它,而不是代码的其他部分。
我还会将 &order_number
括在单引号内,以防它是一个可能导致无效 PL/SQL 和编译错误而不是 运行 时错误的字符串。
declare
v_order_no number(10);
var number(10);
begin
begin
v_order_no := '&order_number';
exception
when value_error then
raise_application_error
( -20000, '"&order_number" is not a numeric order number', true);
end;
select 1 into var from dual where v_order_no > 0;
dbms_output.put_line('var = ' || var);
exception
when no_data_found then
dbms_output.put_line('ndf');
end;
现在,如果你 运行 它与 order_number = 123x
,赋值 v_order_no := '123x'
完全失败:
ORA-20000: "123x" is not a numeric order number
ORA-06512: at line 9
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
如果不加引号,编译会失败:
v_order_no := 123x
*
ERROR at line 6:
ORA-06550: line 6, column 26:
PLS-00103: Encountered the symbol "X" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
The symbol "; was inserted before "X" to continue.
有没有办法将这个错误(ORA-06502:PL/SQL:数字或值错误:字符到数字转换错误)捕获到异常中?每当我使用字符串作为输入时,就会发生这种情况。我以为其他人的异常会抓住它,但它不会。
DECLARE
v_order_no NUMBER(10) := &Order_Number;
var NUMBER(10);
BEGIN
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
正确的例外是VALUE_ERROR
。但是,OTHERS
也应该捕获该错误。您的代码的问题是在块的声明部分中抛出了异常。如果您在 BEGIN
之后移动该分配,您应该能够捕获该异常。
DECLARE
v_order_no NUMBER(10);
var NUMBER(10);
BEGIN
v_order_no := &Order_Number;
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN VALUE_ERROR THEN
dbms_output.put_line('value_error');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
放置一个额外的 Begin
和 END
块应该可以解决您的问题并且应该捕获异常,但是 @pablomatico 建议的是编写块的正确方法。如果您想坚持使用自己的代码,您可以这样做:
BEGIN
DECLARE
v_order_no NUMBER(10) := &Order_Number;
var NUMBER(10);
BEGIN
SELECT 1 INTO var
FROM tbl
WHERE col = v_order_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('ndf');
WHEN OTHERS THEN
dbms_output.put_line('Error');
END;
END;
我会给分配它自己的子块,这样你就可以保证任何验证错误都来自它,而不是代码的其他部分。
我还会将 &order_number
括在单引号内,以防它是一个可能导致无效 PL/SQL 和编译错误而不是 运行 时错误的字符串。
declare
v_order_no number(10);
var number(10);
begin
begin
v_order_no := '&order_number';
exception
when value_error then
raise_application_error
( -20000, '"&order_number" is not a numeric order number', true);
end;
select 1 into var from dual where v_order_no > 0;
dbms_output.put_line('var = ' || var);
exception
when no_data_found then
dbms_output.put_line('ndf');
end;
现在,如果你 运行 它与 order_number = 123x
,赋值 v_order_no := '123x'
完全失败:
ORA-20000: "123x" is not a numeric order number
ORA-06512: at line 9
ORA-06502: PL/SQL: numeric or value error: character to number conversion error
如果不加引号,编译会失败:
v_order_no := 123x
*
ERROR at line 6:
ORA-06550: line 6, column 26:
PLS-00103: Encountered the symbol "X" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
The symbol "; was inserted before "X" to continue.