文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  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 節「游標」NOT FOUND 條件也會發生在未擷取任何列的 SELECT ... INTO var_list 陳述式中。

  • 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 陳述式不存在,則在第二個 INSERTPRIMARY KEY 限制而失敗後,MySQL 會採取預設動作 (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;