文件首頁
MySQL 9.0 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  DECLARE ... HANDLER 陳述式

15.6.7.2 DECLARE ... HANDLER 陳述式

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
}

DECLARE ... HANDLER 陳述式指定一個處理一或多個條件的處理常式。如果其中一個條件發生,將會執行指定的 statementstatement 可以是一個簡單的陳述式,例如 SET var_name = value,或是一個使用 BEGINEND 撰寫的複合陳述式(請參閱第 15.6.1 節,「BEGIN ... END 複合陳述式」)。

處理常式的宣告必須出現在變數或條件宣告之後。

handler_action 值表示處理常式在執行處理常式陳述式後所採取的動作。

  • CONTINUE:繼續執行目前的程式。

  • EXIT:終止宣告處理常式的 BEGIN ... END 複合陳述式的執行。即使條件發生在內部區塊中,也是如此。

  • UNDO:不支援。

DECLARE ... HANDLERcondition_value 表示會啟動處理常式的特定條件或條件類別。它可以採用以下形式:

  • mysql_error_code:一個整數常值,表示 MySQL 錯誤代碼,例如 1051 表示 未知資料表

    DECLARE CONTINUE HANDLER FOR 1051
      BEGIN
        -- body of handler
      END;

    請勿使用 MySQL 錯誤代碼 0,因為它表示成功而不是錯誤條件。如需 MySQL 錯誤代碼的清單,請參閱伺服器錯誤訊息參考

  • SQLSTATE [VALUE] sqlstate_value:一個 5 個字元的字串常值,表示 SQLSTATE 值,例如 '42S01' 表示 未知資料表

    DECLARE CONTINUE HANDLER FOR SQLSTATE '42S02'
      BEGIN
        -- body of handler
      END;

    請勿使用以 '00' 開頭的 SQLSTATE 值,因為它們表示成功而不是錯誤條件。如需 SQLSTATE 值的清單,請參閱伺服器錯誤訊息參考

  • condition_name:先前使用 DECLARE ... CONDITION 指定的條件名稱。條件名稱可以與 MySQL 錯誤代碼或 SQLSTATE 值相關聯。請參閱第 15.6.7.1 節,「DECLARE ... CONDITION 陳述式」

  • SQLWARNING:以 '01' 開頭的 SQLSTATE 值類別的簡寫。

    DECLARE CONTINUE HANDLER FOR SQLWARNING
      BEGIN
        -- body of handler
      END;
  • NOT FOUND:以 '02' 開頭的 SQLSTATE 值類別的簡寫。這在游標的上下文中很重要,用於控制當游標到達資料集的末尾時發生的情況。如果沒有更多列可用,則會發生 SQLSTATE 值為 '02000' 的「無資料」條件。若要偵測此條件,您可以為它或 NOT FOUND 條件設定處理常式。

    DECLARE CONTINUE HANDLER FOR NOT FOUND
      BEGIN
        -- body of handler
      END;

    另一個範例,請參閱第 15.6.6 節,「游標」SELECT ... INTO var_list 陳述式如果沒有檢索到任何列,也會發生 NOT FOUND 條件。

  • SQLEXCEPTION:不以 '00''01''02' 開頭的 SQLSTATE 值類別的簡寫。

    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
      BEGIN
        -- body of handler
      END;

如需有關伺服器在發生條件時如何選擇處理常式的資訊,請參閱第 15.6.7.6 節,「處理常式的範圍規則」

如果發生未宣告任何處理常式的條件,則採取的動作取決於條件類別。

  • 對於 SQLEXCEPTION 條件,儲存的程式會在引發條件的陳述式處終止,如同存在 EXIT 處理常式一樣。如果程式是由另一個儲存的程式呼叫的,則呼叫程式會使用應用於其自身處理常式的處理常式選擇規則來處理條件。

  • 對於 SQLWARNING 條件,程式會繼續執行,如同存在 CONTINUE 處理常式一樣。

  • 對於 NOT FOUND 條件,如果條件是正常引發的,則動作為 CONTINUE。如果是由 SIGNALRESIGNAL 引發的,則動作為 EXIT

以下範例使用 SQLSTATE '23000' 的處理常式,該條件會在發生重複鍵錯誤時出現。

mysql> CREATE TABLE test.t (s1 INT, PRIMARY KEY (s1));
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter //

mysql> CREATE PROCEDURE handlerdemo ()
       BEGIN
         DECLARE CONTINUE HANDLER FOR SQLSTATE '23000' SET @x2 = 1;
         SET @x = 1;
         INSERT INTO test.t VALUES (1);
         SET @x = 2;
         INSERT INTO test.t VALUES (1);
         SET @x = 3;
       END;
       //
Query OK, 0 rows affected (0.00 sec)

mysql> CALL handlerdemo()//
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @x//
    +------+
    | @x   |
    +------+
    | 3    |
    +------+
    1 row in set (0.00 sec)

請注意,程序執行後,@x3,這表示在錯誤發生後,執行會繼續到程序的結尾。如果沒有 DECLARE ... HANDLER 陳述式,MySQL 在第二個 INSERTPRIMARY KEY 限制而失敗後,會採取預設動作 (EXIT),而 SELECT @x 將會傳回 2

若要忽略條件,請為其宣告 CONTINUE 處理常式,並將其與空的區塊相關聯。例如:

DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;

區塊標籤的範圍不包含區塊內宣告的處理常式的程式碼。因此,與處理常式相關聯的陳述式不能使用 ITERATELEAVE 來參照包圍處理常式宣告的區塊的標籤。請考慮以下範例,其中 REPEAT 區塊具有 retry 的標籤:

CREATE PROCEDURE p ()
BEGIN
  DECLARE i INT DEFAULT 3;
  retry:
    REPEAT
      BEGIN
        DECLARE CONTINUE HANDLER FOR SQLWARNING
          BEGIN
            ITERATE retry;    # illegal
          END;
        IF i < 0 THEN
          LEAVE retry;        # legal
        END IF;
        SET i = i - 1;
      END;
    UNTIL FALSE END REPEAT;
END;

retry 標籤在區塊內的 IF 陳述式的範圍內。它不在 CONTINUE 處理常式的範圍內,因此該處的參考無效,並會導致錯誤。

ERROR 1308 (42000): LEAVE with no matching label: retry

若要避免在處理常式中參考外部標籤,請使用以下其中一種策略:

  • 若要離開區塊,請使用 EXIT 處理常式。如果不需要區塊清除,BEGIN ... END 處理常式主體可以為空。

    DECLARE EXIT HANDLER FOR SQLWARNING BEGIN END;

    否則,請將清除陳述式放入處理常式主體中。

    DECLARE EXIT HANDLER FOR SQLWARNING
      BEGIN
        block cleanup statements
      END;
  • 若要繼續執行,請在 CONTINUE 處理常式中設定狀態變數,該變數可在封閉區塊中檢查,以判斷是否已叫用處理常式。以下範例使用變數 done 來達到此目的。

    CREATE PROCEDURE p ()
    BEGIN
      DECLARE i INT DEFAULT 3;
      DECLARE done INT DEFAULT FALSE;
      retry:
        REPEAT
          BEGIN
            DECLARE CONTINUE HANDLER FOR SQLWARNING
              BEGIN
                SET done = TRUE;
              END;
            IF done OR i < 0 THEN
              LEAVE retry;
            END IF;
            SET i = i - 1;
          END;
        UNTIL FALSE END REPEAT;
    END;