MySQLにおける制御フローの基礎
一般的なプログラミング言語と同様に、SQLの実行フローは以下の3つに大別されます。
- 順次構造:上から下へ順番に実行される
- 分岐構造:条件に合致した処理を選択して実行する
- 反復構造:特定の条件を満たす間、処理を繰り返す
MySQLでこれらの制御フローを実現するステートメントは、ストアドプロシージャ、ストアドファンクション、トリガー、イベントといったストアドプログラム内でのみ記述可能です。主なステートメントは以下の通りです。
- 条件分岐:
IF、CASE - ループ処理:
LOOP、WHILE、REPEAT - ループ制御:
ITERATE、LEAVE
条件分岐:IFステートメント
構文
IFで始まりEND IFで終了します。条件が真の場合にTHEN以降の処理が実行されます。ELSEIFやELSEは必要に応じて追加し、ELSEの後には条件やTHENを記述しません。
IF condition1 THEN statement1
[ELSEIF condition2 THEN statement2] ...
[ELSE statementN]
END IF;
実装例1:ローカル変数を用いた判定
変数の値を直接評価し、条件ごとに異なるメッセージを返すストアドプロシージャの例です。ここではユーザーのスコアを基準に評価を行います。
DELIMITER //
CREATE PROCEDURE EvaluateScore()
BEGIN
DECLARE user_score INT DEFAULT 85;
DECLARE user_status VARCHAR(20);
IF user_score < 40 THEN
SET user_status = 'Needs Improvement';
ELSEIF user_score < 75 THEN
SET user_status = 'Average';
ELSE
SET user_status = 'Excellent';
END IF;
SELECT user_status AS Result;
END //
DELIMITER ;
-- 実行
CALL EvaluateScore();
-- 削除
DROP PROCEDURE EvaluateScore;
実装例2:テーブルのデータを用いた判定
データベースの値を取得し、その値に基づいて分岐処理を行う例です。まず、商品の売上データを管理するテーブルを作成します。
CREATE TABLE t_product_sales (
product_name VARCHAR(50) NOT NULL,
category VARCHAR(50) NOT NULL,
sales_amount INT NOT NULL
);
INSERT INTO t_product_sales VALUES ('Laptop Pro', 'Electronics', 1200);
INSERT INTO t_product_sales VALUES ('Office Chair', 'Furniture', 3200);
INSERT INTO t_product_sales VALUES ('Smartphone X', 'Electronics', 8500);
INSERT INTO t_product_sales VALUES ('Wooden Desk', 'Furniture', 1800);
このテーブルに対し、以下のルールで売上ランクを判定します。
- 売上が3000以下で、かつカテゴリが'Electronics'の場合:Low Demand
- 売上が3000より大きく8000未満の場合:Medium Demand
- それ以外の場合:High Demand
DELIMITER //
CREATE PROCEDURE CheckProductDemand(
IN p_name VARCHAR(50),
OUT p_demand_level VARCHAR(20)
)
BEGIN
DECLARE v_category VARCHAR(50);
DECLARE v_sales INT;
-- テーブルから対象データを取得して変数に格納
SELECT category, sales_amount
INTO v_category, v_sales
FROM t_product_sales
WHERE product_name = p_name;
-- 条件分岐
IF v_sales <= 3000 AND v_category = 'Electronics' THEN
SET p_demand_level = 'Low Demand';
ELSEIF v_sales > 3000 AND v_sales < 8000 THEN
SET p_demand_level = 'Medium Demand';
ELSE
SET p_demand_level = 'High Demand';
END IF;
END //
DELIMITER ;
-- 実行例
CALL CheckProductDemand('Laptop Pro', @demand);
SELECT @demand;