PL/SQL块中还可以包含其他子块,即嵌套,在代码块的异常处理部分和执行部分都允许在嵌套块,但是在声明部分不允许存在嵌套块。
让我们来研究下下面的这个例子,创建一个带有两个嵌套块的匿名块,且这两个嵌套块是在同一个嵌套层次上。
DECLARE
v_neusoft AUTHORS.FIRST_NAME%TYPE;
BEGIN
-- the first nested block
BEGIN
SELECT first_name
INTO v_neusoft
FROM authors
WHERE UPPER(last_name) = 'NIMENG';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE('EXCEPTION HANDLER for nested block 1');
DBMS_OUTPUT.PUT_LINE(' ');
NULL;
END;
-- the second nested block
BEGIN
SELECT first_name
INTO v_neusoft
FROM authors
WHERE UPPER(last_name) = 'HARDMAN';
EXCEPTION
WHEN TOO_MANY_ROWS
THEN
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('EXCEPTION HANDLER for nested block 2');
END;
END;
让我们从这里例子中来理解嵌套块的使用,以及嵌套块异常处理的规则。
两个嵌套块都有异常,而且都有异常处理子程序。在第一个嵌套块中,我们检索不到任何数据,由于检索的值为NULL,因此引发ORA-1403 no data found 异常,这里我们使用内置NO_DATA_FOUND异常,只要发生ORA-1403 no data found 异常,我们就可以捕获它。在第二个嵌套块中,我们检索出多条数据,导致发生 too many rows 异常,这里我们依然使用内置异常 TOO_MANY_ROWS来捕获它。
执行结果,打印出了:
EXCEPTION HANDLER for nested block 1
EXCEPTION HANDLER for nested block 2
从执行结果中,我们发现了什么?这里发生了一个很有趣的现象,第一个嵌套块中查询语句发生了异常,第二个嵌套块中的查询语句依然执行。而如果这两条查询语句是在同一个大块中,而不是在两个嵌套块中,执行结果是什么?读者你可能猜的到?
执行结果,打印出了:
EXCEPTION HANDLER for nested block 1
这说明,如果两条查询语句是在同一个大块中,而不是在两个嵌套块中,第一个查询语句发生的异常,使所有其余代码都不能执行。
亲爱的的读者,通过这个例子,您可掌握了嵌套块的使用,以及异常处理的规则?
读者还要注意第一个嵌套块中的异常处理部分以NULL结尾,表示下面要忽略这里薄面的一擦和那个,Oracle就会像什么异常都没有发生过一样,继续处理第二条查询语句了。
希望能对您有用!
更多Oracle相关信息见 专题页面