MySQL の REPEAT 文

ここでは MySQL の REPEAT 文についてご説明します。

MySQL の REPEAT 文の使い方

MySQL では、ストーアドプログラム内のフロー制御で REPEAT 文を使って、指定した条件が True を返すまで、繰り返しステートメントを実行することができます。

REPEAT 文の基本的な構文は次の通りです。

[開始ラベル:] REPEAT
	繰り返したいステートメント
UNTIL 条件文
END REPEAT [終了ラベル];

UNTIL の条件文が True を返すまで、「繰り返したいステートメント」を繰り返し実行します。

REPEAT 文では、条件文のチェックは最後に行われるので、「繰り返したいステートメント」は少なくとも一回は実行されます。

開始と終了ラベルはオプショナルですが、つける場合は同じラベル名でなくてはならず、後でご説明する LEAVE 文や ITERATE 文で使います。


それでは、REPEAT 文を実際に使ってみましょう。

今回は REPEAT 文を使って、引数として渡した start_idx から end_idx までの数をカンマでつなげるだけの簡単なストアードプロシージャを作ります。

DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test (start_idx INT, end_idx INT)
BEGIN

	DECLARE result VARCHAR(500) DEFAULT '';

	REPEAT
		SET result = CONCAT(result, start_idx, ',');
		SET start_idx = start_idx + 1;
	UNTIL start_idx > end_idx
	END REPEAT;

	IF CHAR_LENGTH(result) > 1 THEN
		SET result = LEFT(result, CHAR_LENGTH(result) - 1);
    END IF;
    
	SELECT result;
    
END//
DELIMITER ;

8 行目~12 行目で REPEAT 文を使っています。

9 行目では result という変数に start_idx とカンマを追加しています。

10 行目では start_idx に 1 を足しています。

11 行目で start_idx > end_idx かチェックし、False の間、9 行目と 10 行目のステートメントが繰り返し実行されます。

13 ~ 15 行目は result の一番後ろのカンマを取り除いているだけです。


このストアードプロシージャを作成して、start_idx = 1、end_idx = 10 で実行すると次のようになります。

CALL test(1, 10);

[実行結果]

MySQL の REPEAT 1

MySQL の REPEAT 2

result に 1,2,3,4,5,6,7,8,9,10 が入っていて、10 回ループされて start_idx > end_idx となった時にループが終わっていることがわかります。


REPEAT 文は「繰り返したいステートメント」が一回は実行されるので、最初から start_idx > end_idx が True となるような引数を渡しても 9 ~ 10 行目が一回は実行されます。

CALL test(2, 1);

MySQL の REPEAT 3


MySQL の REPEAT 文で BREAK する (LEAVE)

MySQL で REPEAT 文の途中でループを抜けたい(BREAK したい)時には、LEAVE 文を使って抜けることができます。

DO と END REPEAT の間の繰り返したいステートメントの中で、LEAVE ラベル名; のように指定します。

ラベル名: REPEAT
	...
	LEAVE ラベル名;
	...
UNTIL 条件文
END REPEAT ラベル名

例えば、ループ中に result の文字の長さが 5 以上になったらループを抜けたいのであれば、次のようにできます。

DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test (start_idx INT, end_idx INT)
BEGIN

	DECLARE result VARCHAR(500) DEFAULT '';

	repeat_loop1: REPEAT
		SET result = CONCAT(result, start_idx, ',');
		IF CHAR_LENGTH(result) >= 5 THEN
			LEAVE repeat_loop1;
		END IF;  
		SET start_idx = start_idx + 1;
	UNTIL start_idx > end_idx
	END REPEAT repeat_loop1;

	IF CHAR_LENGTH(result) > 1 THEN
		SET result = LEFT(result, CHAR_LENGTH(result) - 1);
    END IF;
    
	SELECT result;
    
END//
DELIMITER ;

8 行目の REPEAT の前に開始ラベルの repeat_loop1: を、15 行目の END REPEAT の後に終了ラベルの repeat_loop1 を追加します。

10 ~ 12 行目で result の文字数をチェックし、5 以上であれば LEAVE repeat_loop1; でループを抜けています。


このクエリーを実行して test ストアードプロシージャを再生成し、start_idx = 1、end_idx = 10 で実行すると次のようになります。

CALL test(1, 10);

[実行結果]

MySQL の REPEAT 4

result には 1,2,3 のみが入っていて、result の文字数が 5 以上になった時に REPEAT 文のループを抜けているのがわかります。


MySQL の REPEAT 文で CONTINUE する (ITERATE)

MySQL で REPEAT 文の途中で、その後のステートメントをスキップしてループの実行を続けたい(CONTINUE したい)時には、ITERATE 文を使って行うことができます。

ITERATE 文は ITERATE ラベル名; のように使い、指定したラベルのループを最初から実行します。

ラベル名: REPEAT
	...
	ITERATE ラベル名;
	...
UNTIL 条件文
END REPEAT ラベル名

例えば、ITERATE 文を使って、start_idx が奇数の時のみ result に文字列を追加したいのであれば、次のようにできます。

DROP PROCEDURE IF EXISTS test;
DELIMITER //
CREATE PROCEDURE test (start_idx INT, end_idx INT)
BEGIN

	DECLARE result VARCHAR(500) DEFAULT '';

	repeat_loop1: REPEAT
    	IF start_idx % 2 = 0 THEN
			SET start_idx = start_idx + 1;
			ITERATE repeat_loop1;
		END IF;  
		SET result = CONCAT(result, start_idx, ',');
		SET start_idx = start_idx + 1;
	UNTIL start_idx > end_idx
	END REPEAT repeat_loop1;

	IF CHAR_LENGTH(result) > 1 THEN
		SET result = LEFT(result, CHAR_LENGTH(result) - 1);
    END IF;
    
	SELECT result;
    
END//
DELIMITER ;

9 ~ 12 行目で start_idx を 2 で割った余りが 0 の時は start_idx に 1 を足してから、ITERATE repeat_loop1; でループの最初から実行するようにしています。

ここで ITERATE 文の前に start_idx に 1 を足すのを忘れると、UNTIL の条件文がずっと True になり、無限ループになってしまうのでお気をつけください。


このクエリーを実行して test ストアードプロシージャを再生成し、start_idx = 1、end_idx = 10 で実行すると次のようになります。

CALL test(1, 10);

[実行結果]

MySQL の REPEAT 5

result には 1,3,5,7,9,11 が入っていて、偶数の時は ITERATE 文以降のステートメントが実行されずに、 REPEAT 文のループが継続されているのがわかります。

ですが、本来は 10 で終わりたかったところが 11 まで reesult に入ってしまっています。

これは、start_idx が 10 の時に ITERATE 文の前の SET start_idx = start_idx + 1 で start_idx が 11 になりますが、その時に条件文のチェックが行われずにループの最初に戻り、9 ~ 10 行目が実行される為です。

10 で終わらせるためには、LEAVE 文を併用するなど工夫する必要があります。


REPEAT 文は、条件を最後にチェックするため、このようなケースや、条件文が False の状態でも最低一回は実行されるなど、少し注意が必要です。

ループしたい時は、REPEAT 文よりも WHILE 文 や LOOP 文のほうがわかりやすいので不具合になりにくく、使いやすいかもしれません。


以上、MySQL の REPEAT 文についてご説明しました。

© 2024 MySQL 入門