13.6.7.2 DECLARE ... HANDLER 구문
DECLAREhandler_action
HANDLER FORcondition_value
[,condition_value
] ...statement
handler_action
: CONTINUE | EXIT | UNDOcondition_value
:mysql_error_code
| SQLSTATE [VALUE]sqlstate_value
|condition_name
| SQLWARNING | NOT FOUND | SQLEXCEPTION
DECLARE ... HANDLER
문은 하나 이상의 조건을 처리하는 핸들러를 지정합니다. 이러한 조건 중 하나가 발생하면, 지정된 statement
가 실행됩니다. statement
는 SET
등의 간단한 명령문은 var_name
= value
BEGIN
과 END
를 사용하여 작성된 복합 문이 될 수 있습니다 ( 섹션 13.6.1 "BEGIN ... END 복합 문"부분 을 참조하십시오) .
핸들러 선언은 변수 나 조건 선언 다음에 지정해야합니다.
handler_action
값은 핸들러 문을 실행 한 후 핸들러가 어떤 작업을 수행하는 방법을 보여줍니다.
CONTINUE
: 현재 프로그램의 실행이 계속됩니다.EXIT
:이 핸들러가 선언 된BEGIN ... END
복합 명령문의 실행이 종료됩니다. 이것은이 조건이 내부의 블록에서 발생하는 경우에도 마찬가지입니다.UNDO
: 지원되지 않습니다.
DECLARE ... HANDLER
의 condition_value
이 핸들러를 활성화하는 구체적인 조건 또는 조건의 클래스를 나타냅니다.
MySQL 오류 코드 (번호) 또는 SQLSTATE 값 (5 문자열 리터럴). MySQL 오류 코드 0 또는
'00'
로 시작하는 SQLSTATE 값은 오류 조건이 아닌 성공을 설명하기 위해 사용해서는 없습니다. MySQL 오류 코드 및 SQLSTATE 값의 목록은 섹션 B.3 "서버 오류 코드 및 메시지" 를 참조하십시오.이전에
DECLARE ... CONDITION
에서 지정된 조건 이름. 조건 이름은 MySQL 오류 코드 또는 SQLSTATE 값에 연결할 수 있습니다. 섹션 13.6.7.1 "DECLARE ... CONDITION 구문" 을 참조하십시오.SQLWARNING
는'01'
로 시작하는 SQLSTATE 값 클래스의 줄임말입니다.NOT FOUND
는'02'
로 시작하는 SQLSTATE 값 클래스의 줄임말입니다. 이것은 커서의 컨텍스트에 관계하고 커서가 데이터 세트의 끝에 도달했을 때의 동작을 제어하는 데 사용합니다. 그 이상의 행을 취득 할 수없는 경우 SQLSTATE 값'02000'
에서 "데이터 없음"상황이 발생합니다. 이 상황을 감지하려면 그 상황 (또는NOT FOUND
상황)의 핸들러를 설정할 수 있습니다. 예를 들어, 섹션 13.6.6 "커서" 를 참조하십시오. 이 상황은 행이 검색되지 않는SELECT ... INTO
문에서도 발생합니다.var_list
SQLEXCEPTION
은'00'
,'01'
또는'02'
로 시작하지 않는 SQLSTATE 값 클래스의 줄임말입니다.
조건이 발생했을 때 서버가 핸들러를 선택하는 방법은 섹션 13.6.7.6 "핸들러의 범위에 관한 규칙" 을 참조하십시오.
해당 핸들러가 선언되지 않은 조건이 발생하는 경우 수행되는 작업은 그 조건의 클래스에 따라 다릅니다.
SQLEXCEPTION
조건의 경우EXIT
핸들러가 존재하는 것처럼 저장된 프로그램은 그 조건을 발생시킨 문으로 종료합니다. 그 프로그램이 다른 저장 프로그램에서 호출 된 경우 호출 프로그램이 자신의 핸들러에 적용되는 핸들러 선택 규칙을 사용하여 조건을 처리합니다.SQLWARNING
조건의 경우CONTINUE
핸들러가 존재하는 것처럼 프로그램 실행을 계속합니다.NOT FOUND
조건에서는 그 조건이 정상적으로 발생했을 경우, 액션은CONTINUE
입니다.SIGNAL
또는RESIGNAL
의해 발생했을 경우, 액션은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)
이 프로 시저를 실행 한 후 @x
가 3
으로되어 있는지 확인하십시오. 이 오류가 발생한 후 프로 시저의 마지막까지 계속 실행되었음을 보여줍니다. DECLARE ... HANDLER
문이 존재하지 않았다고하면 PRIMARY KEY
제약으로 인해 두 번째 INSERT
가 실패한 후에 MySQL은 기본 동작 ( EXIT
)을 실행하기 위해 SELECT @x
는 2
를 반환했습니다 했다.
조건을 무시하려면 그 조건의 CONTINUE
핸들러를 선언하고 그것을 빈 블록에 연결합니다. 예 :
DECLARE CONTINUE HANDLER FOR SQLWARNING BEGIN END;
블록 레이블 범위는 블록 내에서 선언 된 핸들러의 코드는 포함되지 않습니다. 따라서 핸들러에 연결된 문은 ITERATE
또는 LEAVE
를 사용하여 처리기 선언을 둘러싸고 블록의 라벨을 참조 할 수 없습니다. 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;