成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

plsql的錯(cuò)誤信息與異常處理

7 錯(cuò)誤消息與異常處理

7.1 異常的介紹

(1) 處理異常分為三個(gè)步驟:
  A 聲明異常
  B 引發(fā)異常
  C 處理異常

(2) 異常的特征
  A 錯(cuò)誤類型: ORA-xxxxx  運(yùn)行時(shí)錯(cuò)誤
               PLS-xxxxx  編譯錯(cuò)誤
  B 錯(cuò)誤代碼:xxxxx
  C 錯(cuò)誤的文本描述

案例1:編譯錯(cuò)誤的案例PLS

SQL> create or replace procedure p1 is
  2  begin
  3  null;
  4  end;
  5  /

Procedure created.

SQL> create or replace procedure p1 is
  2  begin
  3  null           --特意不寫分號(hào)
  4  end;
  5  /

Warning: Procedure created with compilation errors.         --出現(xiàn)警告

SQL> show error     --查看錯(cuò)誤消息
Errors for PROCEDURE P1:

LINE/COL ERROR
-------- -----------------------------------------------------------------
4/1     PLS-00103: Encountered the symbol "END" when expecting one of the
     following:
     ;
     The symbol ";" was substituted for "END" to continue.

案例2:運(yùn)行時(shí)錯(cuò)誤 -- 在編譯的時(shí)候沒有錯(cuò)誤,但是在執(zhí)行的時(shí)候發(fā)生錯(cuò)誤。

SQL> create or replace procedure p2 is
  2   v_descr varchar2(20);
  3  begin
  4   select hrc_descr
  5     into v_descr
  6    from hrc_tab
  7   where hrc_code=8;
  8  dbms_output.put_line(to_char(v_descr));
  9  end;
 10  /

Procedure created.

SQL> exec p2;       --運(yùn)行一個(gè)存儲(chǔ)過程
BEGIN p2; END;

*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "PLSQL.P2", line 4
ORA-06512: at line 1

總結(jié):
 A PLSQL錯(cuò)誤 -- 編譯錯(cuò)誤,在執(zhí)行之前就已經(jīng)報(bào)錯(cuò),需要檢查程序,修改程序,debug
 B ORA錯(cuò)誤   -- 運(yùn)行時(shí)錯(cuò)誤,出現(xiàn)這種錯(cuò)誤的時(shí)候需要手工處理,可以采用第三方軟件的單步調(diào)試方式處理

(2) 異常處理中的聲明,分為三個(gè)部分

 A exception聲明,在聲明自己定義異常的時(shí)候需要用到這個(gè)方法。
 B raise語(yǔ)句:顯示地引發(fā)異常
 C pragma excetption_init 這個(gè)指令可以將oracle錯(cuò)誤和自己定義異常關(guān)聯(lián)起來

 函數(shù)(需要定義變量來接收)
     
    sqlcode -- 返回錯(cuò)誤的代碼號(hào),如果沒有錯(cuò)誤就返回0,可以根據(jù)sqlcode返回的值查詢官方文檔,獲得更詳細(xì)的錯(cuò)誤描述
    sqlerrm -- 返回錯(cuò)誤的文本描述,如果沒有錯(cuò)誤返回normal或者successful completion,也就是官方文檔定義的錯(cuò)誤

(3) 異常處理的常見案例
declare
  v_descr varchar2(20);
begin
  select hrc_descr
    into v_descr
    from hrc_tab
   where hrc_code=8;
  dbms_output.put_line(v_descr);
exception when no_data_found then       --異常的名稱
  dbms_output.put_line('not exists');
end;

no_data_found  --oracle預(yù)定義好的異常的名稱,oracle官方文檔上有每個(gè)異常名稱描述和引發(fā)的場(chǎng)景介紹
《PL/SQL User's Guide and Reference》pdf版本中第264頁(yè)

sqlcode與sqlerrm兩個(gè)函數(shù)的使用

declare
  v_descr varchar2(20);
  v_sqlcode number;
  v_sqlerrm varchar2(200);
begin
  select hrc_descr
    into v_descr
    from hrc_tab
   where hrc_code=8;
  dbms_output.put_line(v_descr);
exception when no_data_found then
  v_sqlcode:=sqlcode;
  v_sqlerrm:=sqlerrm;
  dbms_output.put_line('not exists');
  dbms_output.put_line('ERR: an error with info :'||to_char(v_sqlcode));
  dbms_output.put_line(v_sqlerrm);
end;

輸出:
not exists
ERR: an error with info :100        --100是錯(cuò)誤的代碼號(hào),其他的錯(cuò)誤sqlcode都是ora-后面的號(hào)碼,這個(gè)異常特殊
ORA-01403: no data found            --錯(cuò)誤的描述

對(duì)程序的異常進(jìn)行處理,讓程序不會(huì)在發(fā)生異常

declare
  v_descr varchar2(20);
  v_sqlcode number;
  v_sqlerrm varchar2(200);
begin
  select hrc_descr
    into v_descr
asdfasdg    from hrc_tab
   where hrc_code=8;
  dbms_output.put_line(v_descr);
exception when no_data_found then
  v_sqlcode:=sqlcode;
  v_sqlerrm:=sqlerrm;
  dbms_output.put_line('not exists');
  dbms_output.put_line('ERR: an error with info :'||to_char(v_sqlcode));
  dbms_output.put_line(v_sqlerrm);
  insert into hrc_tab values(8,'asdfasdg');
  commit;
end;

第一次運(yùn)行

輸出:
not exists
ERR: an error with info :100       
ORA-01403: no data found

再一次運(yùn)行
輸出:
asdfasdg

(4)PLSQL異常的功能性分類

  A 預(yù)定義的異常  oracle自己預(yù)先定義好的
  B 用戶自定義的異常

 用戶自定義的異常

declare
  site_s_undefined_for_org exception;
  v_cnt number;
begin
  select count(*) into v_cnt from org_site_tab where org_id=1007;  --本身查詢是沒問題的
  if v_cnt=0 then      --只有在v_cnt值為0的時(shí)候引發(fā)異常
    raise site_s_undefined_for_org;
  end if;
exception when site_s_undefined_for_org then
  dbms_output.put_line('empty table!');
  when others then
  dbms_output.put_line('ERR: an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

--自己定義異常,自己拋出異常,自己處理異常

系統(tǒng)預(yù)定義的異常

DUP_VAL_ON_INDEX   --唯一性約束上有列值的重復(fù)沖突

declare
  site_s_undefined_for_org exception;
  v_cnt number;
begin
  select count(*) into v_cnt from org_site_tab where org_id=1007;  --本身查詢是沒問題的
  insert into hrc_tab values(8,'asfdadsagsa');--這里出現(xiàn)異常,程序就進(jìn)入異常處理部分,后面不再執(zhí)行
  commit;
  if v_cnt=0 then      --只有在v_cnt值為0的時(shí)候引發(fā)異常
    raise site_s_undefined_for_org;
  end if;
exception when site_s_undefined_for_org then
  dbms_output.put_line('empty table!');
  when DUP_VAL_ON_INDEX then
  dbms_output.put_line('value repeat!');
  when others then
  dbms_output.put_line('ERR: an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

輸出:value repeat!

(3) pragma exception_init 指令
 這個(gè)指令就是把oracle的錯(cuò)誤還有用戶自定義異常關(guān)聯(lián)起來

[oracle@test ~]$ oerr ora 02290     --知道錯(cuò)誤號(hào),可以使用該命令查看詳細(xì)錯(cuò)誤
02290, 00000, "check constraint (%s.%s) violated"
// *Cause: The values being inserted do not satisfy the named check
//    constraint.
// *Action: do not insert values that violate the constraint.


select * from user_constraints where table_name='ORG_LEVEL';

SQL> conn plsql/plsql
Connected.
SQL> insert into org_level values(1001,'P');
insert into org_level values(1001,'P')
*
ERROR at line 1:
ORA-02290: check constraint (PLSQL.ORG_LEVEL_CK) violated


declare
  invalid_org_level exception;
  pragma exception_init(invalid_org_level,-2290);  --關(guān)聯(lián)以后,就不需要raise引發(fā)異常
begin
create table exception_monitor(
excep_tab_name varchar2(30),
excep_key varchar2(50),
excep_program varchar2(30),
excep_name varchar2(30),
excep_code number,
excep_txt varchar2(200),
excep_date date
);
  insert into org_level values(1001,'P');
  commit;
exception when invalid_org_level then
  dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
  when others then
  dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

可以讓程序自己拋出

begin
  insert into org_level values(1001,'P');
  commit;
exception
  when others then
  dbms_output.put_line('ERR:an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

##########################################################################################

成都創(chuàng)新互聯(lián)長(zhǎng)期為千余家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營(yíng)造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為阿巴嘎企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì),阿巴嘎網(wǎng)站改版等技術(shù)服務(wù)。擁有10多年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。


7.2 異常監(jiān)控表

(1) 創(chuàng)建一個(gè)異常監(jiān)控表:exception_monitor

字段
   發(fā)生異常的表的名字:    excep_tab_name
   發(fā)生異常的行的主鍵:    excep_key
   發(fā)生異常的程序的名稱:  excep_program,如果是匿名塊就置為null
   異常的名稱:            excep_name 如果沒有定義就寫'others'
   異常的sqlcode:          excep_code
   異常的文本描述:        excep_txt
   發(fā)生異常的時(shí)間:        excep_date

以后編寫程序的時(shí)候都要編寫異常處理部分,獲取到上面這些信息,插入這個(gè)表

創(chuàng)建異常監(jiān)控表:
create table exception_monitor(
excep_tab_name varchar2(30),
excep_key varchar2(50),
excep_program varchar2(30),
excep_name varchar2(30),
excep_code number,
excep_txt varchar2(200),
excep_date date
);

改寫上面的例子:
declare
  invalid_org_level exception;
  pragma exception_init(invalid_org_level,-2290);
  v_sqlcode number;
  v_sqlerrm varchar2(200);
begin
  insert into org_level values(1001,'P');
  commit;
exception when invalid_org_level then
  v_sqlcode:=sqlcode;
  v_sqlerrm:=sqlerrm;
  insert into exception_monitor values('ORG_LEVEL','1001',null,upper('invalid_org_level'),v_sqlcode,v_sqlerrm,sysdate);
  commit;
  when others then
  v_sqlcode:=sqlcode;
  v_sqlerrm:=sqlerrm;
  insert into exception_monitor values('ORG_LEVEL','1001',null,upper('others'),v_sqlcode,v_sqlerrm,sysdate);
  commit;
end;

練習(xí)7:將練習(xí)6那個(gè)程序修改它的異常處理部分,將錯(cuò)誤捕獲到監(jiān)控表

錯(cuò)誤號(hào)的20000~21299是錯(cuò)誤號(hào)的空缺范圍,這個(gè)范圍用來自定義錯(cuò)誤,用內(nèi)置的函數(shù)來引發(fā)這個(gè)錯(cuò)誤。

declare
  site_s_undefined_fo_org exception;
  pragma exception_init(site_s_undefined_fo_org,-20001);
  v_cnt number;
begin
  select count(1) into v_cnt from org_site_tab where org_id=1007;
  if v_cnt=0 then
    raise_application_error(-20001,'this table rows is empty!');
  end if;
exception when site_s_undefined_fo_org then
  dbms_output.put_line(sqlerrm);
  when others then
  dbms_output.put_line('ERR : an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

不關(guān)聯(lián)異常的名稱也可以:

declare
  v_cnt number;
begin
  select count(1) into v_cnt from org_site_tab where org_id=1007;
  if v_cnt=0 then
    raise_application_error(-20001,'this table rows is empty!');
  end if;
exception
  when others then
  dbms_output.put_line('ERR : an error with info :'||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

##########################################################################################

7.3 在聲明部分引發(fā)的異常的處理

注意:異常需要在begin 和 exception 之間才能捕獲到的

declare
  v_cnt number(2):=100;
begin
  null;
exception when others then
  dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

改寫:

begin
  declare
    v_cnt number(2):=100;
  begin
    null;
  exception when others then
    dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
    dbms_output.put_line(sqlerrm);
  end;
exception when others then
  dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

解決方法:將原來的代碼塊嵌套在一個(gè)begin和exception之間即可捕獲到

注意:
 A 程序是從begin開始執(zhí)行的,declare部分不是程序執(zhí)行的部分
 B 異常捕獲的區(qū)間是begin到exception之間的代碼

7.5 在異常部分引發(fā)異常的處理

declare
  condition boolean:=true;
  excep1 exception;
  excep2 exception;
begin
  if condition then
    raise excep1;
  end if;
exception when excep1 then
  raise excep2;
end;

改寫:

declare
  condition boolean:=true;
  excep1 exception;
  excep2 exception;
begin
  if condition then
    raise excep1;
  end if;
exception when excep1 then
  begin
    raise excep2;
  exception when excep2 then
    dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
    dbms_output.put_line(sqlerrm);
  end;
end;

或者

declare
  condition boolean:=true;
  excep1 exception;
  excep2 exception;
begin
  begin
    if condition then
      raise excep1;
    end if;
  exception when excep1 then
    raise excep2;
  end;
exception when excep2 then
  dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

7.6 一個(gè)異??梢员欢啻我l(fā)

declare
  condition boolean:=true;
  excep1 exception;
begin
  begin
    if condition then
      raise excep1;
    end if;
  exception when excep1 then
    raise excep1;
  end;
exception when excep1 then
  dbms_output.put_line('ERR CODE : '||to_char(sqlcode));
  dbms_output.put_line(sqlerrm);
end;

新聞名稱:plsql的錯(cuò)誤信息與異常處理
文章路徑:http://jinyejixie.com/article0/pppdio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站改版、網(wǎng)站維護(hù)品牌網(wǎng)站設(shè)計(jì)、域名注冊(cè)手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化
阿拉尔市| 汝城县| 新昌县| 岗巴县| 灵寿县| 江华| 泸西县| 仁怀市| 峡江县| 商都县| 尖扎县| 广丰县| 乌恰县| 郎溪县| 雅安市| 白城市| 屏山县| 柳林县| 吉水县| 贵阳市| 广州市| 舟曲县| 正定县| 乌兰察布市| 台北县| 周宁县| 南丰县| 柘荣县| 万载县| 三门县| 句容市| 临漳县| 寿阳县| 正安县| 宁远县| 晋中市| 西乡县| 衡山县| 应用必备| 紫云| 信阳市|