単元概要

この単元では、ストアドプロシージャやストアドファンクションでも使用できる繰り返し処理(loop文)を学びます。

重要なポイント

まずはシンプルなループ文を使った、データ操作を学びます!

解説

loop文の使い方

他のプログラム言語と同様に「loop文」を利用する場合には、必ず終了条件を先に入れるようにしましょう。失敗するとサーバが停止するなど大きな事故に繋がります。ストアドプロシージャだけでなく、ストアドファンクションでも同様に使用できます

delimiter //

drop procedure if exists [プロシージャ名];
create procedure [プロシージャ名](in/out [引数名1] [型],in/out [引数名2] [型])
begin
    declare [変数名] int;
    set [変数名] = [値];

    [繰り返しラベル名]: loop

        set [変数名] = [値] + 1;

        if [変数名] > 10 then
            leave [繰り返しラベル名]; -- ループを抜ける
        end if;
        
    end loop [繰り返しラベル名];
    
    select [変数名];
end;
//

delimiter ;

<例題>

  • もし、プロシージャ名「pro001_test」がすでにある場合には、削除すること。
  • プロシージャ名「pro001_test」で作成すること。
  • 引数
    • in/out:in
    • 引数名:start_no
    • 型:int
  • 処理
    1. 処理1:変数名「int_result」(int型)を宣言すること。
    2. 処理2:変数名「str_text」(str型,8000文字)を宣言すること。
    3. 処理3:変数名「int_result」に[start_no]を代入すること。
    4. 処理4:変数名「str_text」を[”(空)]を代入すること。
    5. 処理5:
      1. 繰り返し処理:ラベル名「loop1」
        1. 分岐処理
          • 変数名「str_text」に、下記方法で文字列結合すること。
            • concat関数:concat([文字A],[文字B],[文字C])
              concat(str_text,int_result,’,’)
          • 変数名「int_result」に「+1」すること。
          • 変数名「int_result」が10より大きい場合には、繰り返し処理を抜けること。
    6. 処理6:「str_text」を表示すること。
delimiter //

drop procedure if exists pro001_test;
create procedure pro001_test(in start_no int)
begin
    declare int_result int;
    declare str_text varchar(8000);
    set int_result = start_no;
    set str_text = '';

    loop1: loop
        set str_text = concat(str_text,int_result,',');
        set int_result = int_result + 1;

        -- 条件に一致した場合、ループを抜ける処理
        if int_result > 10 then
            leave loop1; -- leave(ループ離脱)
        end if;
    end loop loop1;

    select str_text;
end;
//

delimiter ;

/* ストアドプロシージャを呼び出す */
call pro001_test(1);

上記の例題を実行すると2つの問題がありました。

1つ目は、最終行の「call pro001_test(1);」の引数に「call pro001_test(100);」などの10より大きい数値をいれてしまうと下記のような想定しない結果になります。

+----------+
| str_text |
+----------+
| 100, |
+----------+

2つ目は、最後の1文字に「,(カンマ)」がついてしまい、プログラムとしては不完全な状態です。

+-----------------------+
| str_text |
+-----------------------+
| 1,2,3,4,5,6,7,8,9,10, |
+-----------------------+

<例題>

  • 上記の問題を解決するプロシージャを作成すること。
    1. pro001_test()の引数に10より大きい場合には、何も表示されないようにすること。
    2. 現在の結果の最終文字「,(カンマ)」が表示されないようにすること。
      • char_length関数は、文字列の文字数をカウントします。
        char_length([文字列])
      • left関数は、左から指定した文字数で文字列を取り出します。
        left([文字列],[文字数])
        下記の場合は、「総文字数 – 1」した値です。
delimiter //

drop procedure if exists pro001_test;
create procedure pro001_test(in start_no int)
begin
    declare int_result int;
    declare str_text varchar(500);
    set int_result = start_no;
    set str_text = '';

    if int_result <= 10 then
        loop1: loop
            set str_text = concat(str_text,int_result,',');
            set int_result = int_result + 1;
            if int_result > 10 then
                leave loop1;
            end if;
        end loop loop1;
    end if;
    set str_text = left(str_text, char_length(str_text) - 1);
    select str_text;
end;
//

delimiter ;

/* ストアドプロシージャを呼び出す */
call pro001_test(1);
call pro001_test(100);