2010-11-17 80 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. 

但是,這不是一個明智的做法,在一般情況下,編寫存儲程序。您的過程應該知道實際存在哪些表,並且應該在開發過程中識別並解決語法錯誤,而不是在運行時。