• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            異常處理

            ?

            當(dāng)異常生成之后,程序被中止,控制權(quán)交給異常處理模塊,異常處理模塊捕獲當(dāng)前異常句柄,并交由相應(yīng)的程序處理;如果,異常促里模塊沒有捕捉到異常句柄,那么它將被傳輸?shù)疆?dāng)前程序的外圍。

            ?

            除非由一些特殊的要求,一般情況下異常將再當(dāng)前程序的異常處理模塊中被處理。異常處理模塊以 EXCEPTION 開始 END; 結(jié)尾。

            ?????? Declare

            ?????? ?????? /*…………*/

            ?????? begin

            ?????? ?????? /*…………*/

            ?????? exception

            ????????????? when /* 異常名稱 */

            ????????????? then /* 異常處理 */

            ????????????? when other

            ????????????? then /* 異常處理 */

            ?????? end;

            異常處理模塊的語(yǔ)法基本上以 CASE 一致,凡是在 when 中有定義的異常都將被處理,而沒有的則被傳輸。一個(gè)特殊的異常處理語(yǔ)句是 WHEN OTHERS 。就想在( 3 )中所說(shuō)的,它會(huì)處理所有為被處理的異常,因此必須小心使用它,最好是在最外層的程序中。當(dāng)然如果喜歡偷懶的,大可以在異常處理模塊中只放一個(gè) OTHERS 。注意,無(wú)論哪種情況, OTHERS 只能這只在異常處理的最后一位。

            ?

            有趣的是,可以在一個(gè) when 中處理多個(gè)異常句柄。

            ?????? Exception

            ????????????? When no_data_found or invalid_employee_id or dbms_ldap.invalid session

            ????????????? Then /*………..*/

            ?????? End;

            ?????? /

            在這個(gè)例子里,有標(biāo)準(zhǔn)包的異常、自定義異常和非標(biāo)準(zhǔn)包中的異常。這些異常只能用 or 連接,不可以用 and ,因?yàn)橹挥幸粋€(gè)異常能夠生成。

            ?

            raise_application_error 生成的異常,如果沒有被處理而一直傳遞到系統(tǒng)環(huán)境中,那么環(huán)境將視情況作出相應(yīng)的反映。在 sqlplus 中, oracle 將回滾所有 DML 對(duì)數(shù)據(jù)所做的修改。在 sqlplus 環(huán)境中,因?yàn)橛凶詣?dòng)回滾的存在,我們可以保留出現(xiàn)未被處理的異常的可能性;而在另外的一些環(huán)境中,則需要仔細(xì)設(shè)計(jì)最外層程序。

            ü???????? 捕捉任何有可能傳出的異常。

            ü???????? 記錄錯(cuò)誤以便于分析。

            ü???????? 給外部環(huán)境一個(gè)信息,以便于其作出相應(yīng)的處理。

            ?

            對(duì)于自定義異常,因?yàn)?/span> sqlcode 值永遠(yuǎn)是 1 ,所以當(dāng)它被傳出時(shí),如果外圍程序中沒有定義相同名稱的異常,我們將不知道是什么異常產(chǎn)生了。因此,不要將自定義異常傳遞出去。

            ?

            在程序中處理幾個(gè)互相獨(dú)立的操作時(shí),為了避免出現(xiàn)因?yàn)橐粋€(gè)操作產(chǎn)生異常而使整個(gè)程序被中斷的情況,有必要將這些獨(dú)立的操作放在各自的虛擬塊中。

            ?????? Procedure change_data is

            ?????? Begin

            ????????????? Begin

            ????????????? ?????? Delete from employee where …..

            ?????? ?????? Exception

            ????????????? ?????? When others then null;

            ????????????? End;

            ?

            ????????????? Begin

            ????????????? ?????? Update company set …….

            ?????? ?????? Exception

            When others then null;

            ????????????? End;

            ?

            ????????????? Begin

            ????????????? ?????? Insert into company_history select * from company where ….

            ?????? ?????? Exception

            ????????????? ?????? When others then null;

            ????????????? End;

            ?????? End;

            ?????? /

            ?

            ?

            Pl/sql 提供了一些內(nèi)建的函數(shù)來(lái)幫助我們確定、分析異常。

            ?

            SQLCODE

            這個(gè)函數(shù)在前面有提到過(guò),它是一個(gè)用于返回當(dāng)前模塊中最近一次異常值的函數(shù),或者說(shuō)是非入棧程序的異常值。打個(gè)比方:如果在當(dāng)前程序的異常模塊中調(diào)用了另一個(gè)程序, oracle 將當(dāng)前程序及相應(yīng)的環(huán)境變量(包括異常值)壓入系統(tǒng)棧;在被調(diào)用程序中生成了一個(gè)值為 1 的異常,那么 sqlcode 將返回 1 ;之后剛才的程序出棧, sqlcode 返回當(dāng)前異常值。需要注意的是,不要在異常模塊之外使用它,這樣不會(huì)有任何意義。當(dāng)沒有異常或在異常模塊之外使用時(shí), SQLCODE 返回 0 ;返回值 1 是指自定義異常。

            ?

            SQLERRM

            接收異常值,返回相應(yīng)的長(zhǎng)度不超過(guò) 512 字節(jié)的描述語(yǔ)。如果沒有傳入異常值,則返回當(dāng)前異常描述。

            ?????? Begin

            ?????? ?????? Dbms_output.put_line( sqlerrm(-1403);

            ?????? End;

            Sql>/

            Ora-1403: no data found

            在需要體構(gòu)長(zhǎng)度超過(guò) 512 字節(jié)的描述時(shí), oracle 建議使用 dbms_utility.format_error_stack 。顯然,用這個(gè)函數(shù)來(lái)判斷一個(gè)異常是否為系統(tǒng)異常是很有用的,如果不是的話,將返回以下兩種情況的一種。

            如果是一個(gè)負(fù)數(shù):

            ?????? ora-nnnnn: message not found,; product=rdbms; facility=ora

            如果是一個(gè)正數(shù):

            ?????? -nnnnn: non-oracle exception

            ?

            DBMS_UTILITY.FORMAT_ERROR_STACK

            返回當(dāng)前異常相應(yīng)的描述,沒有字符長(zhǎng)度限制。與 SQLCODE 相同的是,必須在異常處理模塊中使用。雖然名稱中有一個(gè) stack 在,但通過(guò)它并不能知道異常的最初生成處,需要的話就必須使用 DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

            ?

            DBMS_UTILITY.FORMAT_ERROR_BACKTRACE

            系統(tǒng)為最近一次生成的異常設(shè)置了一個(gè)棧,并跟蹤它的傳遞過(guò)程,而這個(gè)函數(shù)使用這個(gè)棧,然后返回該異常的整個(gè)傳遞過(guò)程。這個(gè)函數(shù)對(duì)錯(cuò)誤的定位和實(shí)施下一步處理起著至關(guān)重要的作用。

            ?????? Create or replace procedure procl is

            ?????? Begin

            ?????? ?????? Dbms_output.put_line(‘running proc1’);

            ????????????? Raise no_data_found;

            ?????? End;

            ?????? /

            ?????? create or replace procedure proc2 is

            ?????? begin

            ?????? ?????? dbms_output.put_line(‘calling proc1’);

            ????????????? proc1;

            ?????? end;

            ?????? /

            ?????? create or replace procedure proc3 is

            ?????? begin

            ?????? ?????? dbms_output.put_line(‘calling proc2’);

            ????????????? proc2;

            ?????? exception

            ????????????? when no_data_found

            ????????????? then

            ????????????? ?????? dbms_output.put_line(‘error stack at top level’);

            ????????????? ?????? dbms_output.put_line(dbms_utility.format_error_backtrace);

            ?????? end;

            ?????? /

            現(xiàn)在可以運(yùn)行 proc3 來(lái)看看結(jié)果。

            Sql>set serveroutput on;

            Sql>begin

            2???????????????????????? dbms_output.put_line(‘proc3->proc2->proc1 backtrace’);

            3???????????????????????? proc3;

            4???? end;

            5???? /

            ??? Proc3 -> Proc2 -> Proc1 backtrace

            ??? calling proc2

            ??? calling proc1

            ??? running proc1

            ??? Error stack at top level:

            ??? ORA-06512: at "SCOTT.PROC1", line 4

            ??? ORA-06512: at "SCOTT.PROC2", line 5

            ORA-06512: at "SCOTT.PROC3", line 4

            事實(shí)上,每次異常的產(chǎn)生都將重置這個(gè)異常棧,只是最后一次從系統(tǒng)棧出棧的是最外層的程序塊,所以可以清楚地看到異常生成的整個(gè)過(guò)程。上面這個(gè)程序的執(zhí)行過(guò)程是這樣的:首先用 put_line 打印 Proc3 -> Proc2 -> Proc1 backtrace 調(diào)用 proc3 ,當(dāng)前程序入棧 => 打印 calling proc2 ,調(diào)用 proc2 proc3 入棧 => 打印 calling proc1 ,調(diào)用 proc1 proc2 入棧 => 打印 running proc1 ,生成 no_data_found 異常,該異常被壓入異常棧中 =>? proc2 出棧,并檢測(cè)到來(lái)自第 5 行調(diào)用傳遞過(guò)來(lái)的異常,將它在此壓入異常棧 => proc3 出棧,并檢測(cè)到來(lái)自第 4 行調(diào)用傳遞過(guò)來(lái)的異常,將它在此壓入異常棧, dbms_utility.format_error_backtrace 將異常棧中信息反相打印出來(lái) =>? 最外層程序出棧, end

            以下是正確使用這個(gè)函數(shù)的一些注意事項(xiàng):

            ü???????? 在當(dāng)前程序的異常處理模塊中調(diào)用這個(gè)函數(shù)。

            ü???????? 避免在中間程序中使用異常處理模塊。

            這樣異常就能被正確地傳輸?shù)阶钔鈱映绦蛑校⒋蛴〕鲞@個(gè)過(guò)程了。

            Posted on 2006-10-25 16:26 艾凡赫 閱讀(3243) 評(píng)論(2)  編輯 收藏 引用 所屬分類: ORACLE

            Feedback

            # re: oracle-plsql 異常處理( 4 )   回復(fù)  更多評(píng)論   

            2008-03-12 08:13 by 小魚
            頂一下,寫的不錯(cuò)

            # re: oracle-plsql 異常處理( 4 ) [未登錄]  回復(fù)  更多評(píng)論   

            2011-05-27 13:59 by 1
            11
            国产午夜福利精品久久| 国产成人精品免费久久久久| 久久毛片免费看一区二区三区| 久久精品国产欧美日韩| 亚洲欧洲久久久精品| 久久精品国产亚洲77777| 久久久久女教师免费一区| 欧洲人妻丰满av无码久久不卡 | 久久久精品波多野结衣| 久久久无码精品亚洲日韩京东传媒 | 亚洲中文字幕无码久久精品1| 99久久伊人精品综合观看| 久久亚洲私人国产精品vA| 国产成人久久精品二区三区| 欧美黑人激情性久久| 久久丫忘忧草产品| 久久青青草原亚洲av无码| 亚洲成色999久久网站| 久久发布国产伦子伦精品 | 久久精品极品盛宴观看| 国产精品青草久久久久福利99| 热re99久久精品国99热| 色欲久久久天天天综合网| 精品人妻伦九区久久AAA片69 | 深夜久久AAAAA级毛片免费看 | 精品国产青草久久久久福利| 国产亚洲精久久久久久无码AV| 久久国产精品无码HDAV| 久久亚洲私人国产精品| 久久一日本道色综合久久| 国产69精品久久久久9999APGF | www亚洲欲色成人久久精品| 91精品国产综合久久香蕉 | 久久国产AVJUST麻豆| 国内精品久久久久影院老司| 久久亚洲精品国产亚洲老地址 | 久久99国产综合精品女同| 精品国产VA久久久久久久冰 | 久久久久久久亚洲Av无码| 午夜精品久久久久久久| 2020久久精品国产免费|