1. 程式人生 > >MySql儲存過程—8、條件處理(Condition Handling) / 錯誤、異常處理

MySql儲存過程—8、條件處理(Condition Handling) / 錯誤、異常處理

在遊標裡面我們有簡要的介紹了一個NOT FOUND這個條件處理(錯誤、異常處理)的情況,條件處理涉及到兩個語句,一個是DECLARE...CONDITION,另一個是DECLARE....HANDLER。在遊標的例子中是使用了一個DECLARE....HANDLER。先來看看DECLARE....HANDLER。

1、DECLARE....HANDLER語句

這個語句用於但資料庫出現某種情況的時候(condition,大部分指發生某種錯誤時),來定義具體的處理辦法(handler);所以這裡涉及到包括:a、就是個什麼情況 b、如何處理它;下面是其格式

DECLARE handler_action HANDLER
    FOR condition_value [, condition_value] ...
    statement

handler_action:
    CONTINUE
  | EXIT
  | UNDO

condition_value:
    mysql_error_code
  | SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
這裡面需要注意幾點:

      a、condition_value [,condition_value],這個的話說明可以包括多種情況(方括弧表示可選的),也就是一個handler可以定義成針對多種情況進行相應的操作;另外condition_value可以包括的值有上面列出來的6種:

                1、mysql_error_code,這個表示mysql的錯誤程式碼,錯誤程式碼是一個數字,完成是由mysql自己定義的,這個值可以參考mysql資料庫錯誤程式碼及資訊

                2、SQLSTATE [VALUE] sqlstate_value,這個同錯誤程式碼類似形成一一對應的關係,它是一個5個字元組成的字串,關鍵的地方是它從ANSI SQL和ODBC這些標準中引用過來的,因此更加標準化,而不像上面的error_code完全是mysql自己定義給自己用的,這個和第一個類似也可以參考

mysql資料庫錯誤程式碼及資訊

                3、condtion_name,這個是條件名稱,它使用DECLARE...CONDITION語句來定義,這個後面我們會介紹如何定義自己的condition_name。

                4、SQLWARNING,表示SQLTATE中的字串以‘01’起始的那些錯誤,比如Error: 1311 SQLSTATE: 01000 (ER_SP_UNINIT_VAR)

                5、NOT FOUND,表示SQLTATE中的字串以‘02’起始的那些錯誤,比如Error: 1329 SQLSTATE: 02000 (ER_SP_FETCH_NO_DATA

),其實這個錯誤就是用在我們介紹遊標的那個問題所出現的情況,也就是沒有fetch到記錄,也就是我們遊標到記錄的尾巴了的情況。

                6、SQLEXCEPTION,表示SQLSTATE中的字串不是以'00'、'01'、'02' 起始的那些錯誤,這裡'00'起始的SQLSTATE其實表示的是成功執行而不是錯誤,另外兩個就是上面的4和5的兩種情況。

上面的6種情況其實可以分為兩類,一類就是比較明確的處理,就是對指定的錯誤情況進行處理,包括1、2、3這三種方式;另一類是對對應型別的錯誤的處理,就是對某一群錯誤的處理,包括4、5、6這三種方式。這個是介紹了condition_value。另外還要注意的一個內容是MySQL在預設情況下(也就是我們沒有定義處理錯誤的方法-handler)自己的錯誤處理機制:1、對於SQLWARNING和NOT FOUND的處理方法就是無視錯誤繼續執行,所以在遊標的例子裡面如果我們沒有對repeat的條件判斷的那個值做個no_more_products=1的handler來處理,那麼迴圈就會一直下去。2、對於SQLEXCEPTION的話,其預設的處理方法是在出現錯誤的地方就終止掉了。

      b、statement,這個比較簡單就是當出現某種條件/錯誤時,我們要執行的語句,可以是簡單的如 SET  var = value這樣的簡單的語句,也可以是複雜的多行的語句,多行的話可以使用BEGIN  .....  END這裡把語句包括在裡面(這個好比delphi裡面的情況,注意到我們的儲存過程也是多行的,所以也要BEGIN .... END)。

      c、handler_action,這個表示當執行完上面的statement後,希望執行怎樣的動作,這裡包括CONTINUE、EXIT、UNDO,表示繼續、退出、撤銷(暫時不支援)。這邊就是兩種動作,其實這兩種動作在上面也說過了,CONTINUE就是一個是SQLWARNING和NOT FOUND的預設處理方法,而EXIT就是SQLEXCEPTION的預設處理方法。

來看個簡單的例子,這裡建立一個對SQLSTATE的程式碼為'23000'的錯誤(重複的主鍵)進行處理的HANDLER,每次發生時我們對變數@x進行增加1:

DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`ConditionProc` $$
CREATE PROCEDURE `test`.`ConditionProc` ()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x = @x+1;
INSERT INTO products values(1,default,default,default,default,default);
INSERT INTO products values(1,default,default,default,default,default);
SELECT @x;
END $$

DELIMITER ;
程式碼比較簡單,當然這裡我們需要對資料庫進行一點修改,把除了主鍵外其他的欄位設定了預設值,方便測試

測試比較簡單,這裡我們資料庫裡面本身就有記錄了,然後在Qurey browser中先輸入

SET @x = 0;

然後呼叫儲存過程下面是結果:


通過結果我們知道出現了兩次插入的記錄同原有的記錄出現主鍵重複的情況。當然這個是由下面這個程式碼觸發的。

INSERT INTO products values(1,default,default,default,default,default);

2、DECLARE...CONDITION語句

這個語句其實是為了讓我們的錯誤條件更加的清晰明瞭化的,對於上面的情況,像SQLSTATE '23000'這種表示是一種很不直觀的方法,要通過相應的文件去對應,閱讀起來比較不方便。而DECLARE....CONDITION可以對條件定義相對應的名稱,看個例子就清楚了:

DECLARE duplicate_key CONDITION FOR SQLSTATE '23000';
DECLARE CONTINUE HANDLER FOR duplicate_key
  BEGIN
    -- body of handler
  END;
當然在上面的例子我們沒有用到BEGIN....END,我們只有一行SET @[email protected]+1;這裡我們用duplicate_key這個條件名稱來對應到SQLSTATE '23000'上面,這樣檢視起來更加的直觀。這你duplicate_key就是我們上面介紹DECLARE....HANDLER時候的那個condition_name。

相關推薦

MySql儲存過程8條件處理(Condition Handling) / 錯誤異常處理

在遊標裡面我們有簡要的介紹了一個NOT FOUND這個條件處理(錯誤、異常處理)的情況,條件處理涉及到兩個語句,一個是DECLARE...CONDITION,另一個是DECLARE....HANDLER。在遊標的例子中是使用了一個DECLARE....HANDLER。先來看

Mysql儲存過程8:repeat循環

local cal 其他 host ted query code class pan 語法: repeat SQL until 條件 end repeat; 就是相當於其他語言中的: do{ # }while(); mys

mysql儲存過程舉例:100以內的整數除以2468的結果,相加等於多少

學習儲存過程:首先知道它是幹嘛的,  概念:將一組sql語句,完成一個特定的功能,稱之為儲存過程, 寫儲存過程:只能建立、替換、刪除 DROP PROCEDURE IF EXISTS sum; -- procedure 存在則先刪除 create procedure `su

mysql 儲存過程遊標及逐行處理的配合使用

1. 資料準備 +----+------+--------+ | id | name | price1 | +----+------+--------+ | 1 | 大米 | 5 | | 2 | 雞蛋 | 4.5 | | 3 | 蘋果 | 6

MySQL 儲存過程-原理語法函數詳細說明

exp sql 十六進制 作用範圍 安全機制 系統管理員 rtrim 編程 xtra Mysql儲存過程是一組為了完成特定功能的SQL語句集,經過編譯之後存儲在數據庫中,當需要使用該組SQL語句時用戶只需要通過指定儲存過程的名字並給定參數就可以調用執行它了,簡而言之就是一組

MySQL--儲存過程的迴圈語句程式碼筆記--whilerepeat和loop

mysql> delimiter $$ mysql> create table testB -> ( -> id int(6) not null -> ) $$ Query OK, 0 rows affected (0.86 sec) mysq

MySQL-儲存過程程式碼筆記-inoutinoutdeclare區域性變數和if...else語句

mysql> use test; Database changed mysql> show tables; Empty set (0.00 sec) mysql> use test; Database changed mysql> create table testA

MySQL儲存過程之whilerepeat迴圈

一、while迴圈 CREATE DEFINER=`root`@`localhost` PROCEDURE `PRO_WHILE`() BEGIN DECLARE i INT DEFAULT 0; WHILE (i<10) DO /*當滿足條件的時候執行此程式碼塊*/ BE

5分鐘學會MySQL儲存過程_1定義及應用場景

                                          &nb

MySQL 儲存過程-原理語法函式詳細說明

Mysql儲存過程是一組為了完成特定功能的SQL語句集,經過編譯之後儲存在資料庫中,當需要使用該組SQL語句時使用者只需要通過指定儲存過程的名字並給定引數就可以呼叫執行它了,簡而言之就是一組已經寫好的命令,需要使用的時候拿出來用就可以了。想要快速的瞭解Mysql儲存過程嗎,就一同看一下下文的“Mys

mysql儲存過程引數為陣列或者物件的處理方式

問題場景:做一個物品系統, 需要批量存入。 思考:儲存過程的的引數不支援陣列,是否可以用json字串代替 測試用的JSON字串: let obj = { itemlist:[ { regid:0, iteminfo:

修改MySQL儲存過程函式事件觸發器檢視的DEFINER

#修改儲存過程、函式、事件、觸發器、檢視的 DEFINER select definer from mysql.proc; update mysql.proc set definer='[email protected]%'; select DEFINER fro

mysql儲存過程中使用select count(*) into 變數名 from +表+ where條件的用法

select count(*) into v_count from dual where userid=2;此語句的意思就是根據where條件查詢dual表,得到的行數存入變數v_count中(給變數賦值) 只能在儲存過程中編寫這樣的語句?如果在mysql的sql語句中編寫

mysql儲存過程異常處理

DELIMITER $$ USE `mtnoh_aaa_platform`$$ DROP PROCEDURE IF EXISTS `proc_eoms_electric_power_generation_check_engine`$$ CREATE DEFINER=`dwgl`@`%`

關於mysql儲存過程建立動態表名及引數處理

轉載請註明出處:簾卷西風的專欄(http://blog.csdn.net/ljxfblog) 最近遊戲開始第二次內測,開始處理操作日誌,最開始把日誌放到同一個表裡面,發現一天時間,平均100玩家線上,操作記錄就超過13萬條,決定拆表,按照日期來儲存日誌,每天的日誌存到一個表裡

mysql儲存過程procedure 觸發器trigger 遊標cusor 控制語句(條件,迴圈)

什麼是mysql儲存例程? 儲存例程是儲存在資料庫伺服器中的一組sql語句,通過在查詢中呼叫一個指定的名稱來執行這些sql語句命令. 為什麼要使用mysql儲存過程? 我們都知道應用程式分為兩種,一種是基於web,一種是基於桌面,他們都和資料庫進行互動來完成資料

mysql儲存過程檢視等的許可權問題

看儲存過程定義,DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE `DB_U1`.`P1`() /*LANGUAGE SQL | [NOT] DETE

MySql儲存過程—7遊標(Cursor)

1、遊標的作用及屬性 遊標的作用就是用於對查詢資料庫所返回的記錄進行遍歷,以便進行相應的操作;遊標有下面這些屬性:     a、遊標是隻讀的,也就是不能更新它;     b、遊標是不能滾動的,也就是隻能在一個方向上進行遍歷,不能在記錄之間隨意進退,不能跳過某些記錄;    

MySQL儲存過程和自定義函式Navicat for mysql建立儲存過程和函式呼叫儲存過程和函式的區別

與你相遇 好幸運  可我已失去為你淚流滿面的權利  但願在我看不到的天際  你張開了雙翼 1 MySQL儲存過程和函式 過程和函式,它們被編譯後儲存在資料庫中,稱為永續性儲存模組(Persistent Stored Module,PSM),可以反覆呼叫,執行速度快。 1.1 儲存過程 儲存過程是由

淺談 sqlserver 和 mysql儲存過程函式的區別

其實我不太喜歡搞資料庫,平常也就是用用select、insert。這次公司要把資料庫從sqlserver遷到mysql,我也試著改了幾個儲存過程,在此總結。首先吐槽一句,sqlserver和 mysql差別還真大! 區別一:儲存過程入參 USE [LearningRep