2010-11-17 85 views
3

我有这样的代码:甲骨文错误处理

DECLARE 
    e_not_exist EXCEPTION; 
    PRAGMA EXCEPTION_INIT(e_not_exist, -942); 
    car_name VARCHAR2(20); 
BEGIN 
    select name_of_factory into car_name from car where car_id = 1; 
    dbms_output.put_line(car_name); 
EXCEPTION 
    when e_not_exist then 
    dbms_output.put_line('Table or view does not exist'); 
    when OTHERS then 
    dbms_output.put_line(to_char(SQLCODE)); 
END; 

其实,我的表名是汽车,但不是CAR。但是oracle不处理这个异常,并给我一个错误ORA-00942:表或视图不存在。 我该如何处理这个异常?

回答

5

你不能用静态SQL做到这一点。当代码正在编译时,错误即将到来,而不是执行。试试这个:

execute immediate 'select name_of_factory from car where car_id = 1' 
        into car_name ; 
+0

谢谢。据我了解,有编译和运行时错误。如果我知道错误编号,如何识别运行时或编译错误? – maks 2010-11-17 19:59:17

+0

它不是基于数字。从这个例子中可以看出,同样的错误(-942)可以是运行时或编译时基于情况。问题在于,当你使用DECLARE/BEGIN内联时,很难区分它们。一种选择是实际创建一个过程,然后执行它。另一个是做你在这里所做的 - 因为你正在使用'WHEN OTHERS',所有的运行时异常都会以这种方式被捕获,所以弹出的即时错误将会是编译时间。 – Dan 2010-11-17 20:07:51

6

ORA-00942错误通常是一个编译时错误。 Oracle必须在编译时解析表的名称。异常处理程序将在运行时捕获错误,而不是编译时。

如果您使用动态SQL,你可以推迟名称的分辨率运行时,此时你可以捕获该异常,即

SQL> ed 
Wrote file afiedt.buf 

    1 declare 
    2 no_such_table exception; 
    3 pragma exception_init(no_such_table, -942); 
    4 l_cnt integer; 
    5 begin 
    6 execute immediate 'select count(*) from emps' into l_cnt; 
    7 exception 
    8 when no_such_table 
    9 then 
10  dbms_output.put_line('No such table'); 
11* end; 
SQL>/
No such table 

PL/SQL procedure successfully completed. 

但是,这不是一个明智的做法,在一般情况下,编写存储程序。您的过程应该知道实际存在哪些表,并且应该在开发过程中识别并解决语法错误,而不是在运行时。