Whileによる繰り返し処理では、処理の途中で繰り返しを抜け出したり、あるいは冒頭に戻って処理を続けさせたりできます。
- BreakとContinue -
繰り返しを終えるにはBreak、処理を続けるにはContinueを用います。
Break
Whileによる繰り返し処理を抜け、処理をEndの次の行に移行します。
Continue
以降の処理を無視してWhileの条件判定に戻り、繰り返し処理を続けます。
BreakとContinueを使った処理を作ってみましょう。
今度は、商品の販売単価を『最大価格が6,000円以下になるまで10%引きを繰り返す』ことにします。しかし、あまり値引きしすぎると利益が出ないので、『1,000円未満の商品が1件でも現れたら値引きを停止する』ことにしましょう。
処理手順は以下のようになります。これも、ダミーテーブル「商品_dmy」で試します。
(1)最大価格が6,000円以下になるまで繰り返す
(2)販売単価を10%引きする
(3)最低価格が1,000円未満になったら処理をやめる
- 繰り返しの中で条件判断を行う -
これをストアドプロシージャのソースにすると、以下のようになります(ex06.sql)。
Create Procedure PriceDown2
As
While (SELECT MAX(販売単価) FROM 商品_dmy) > 6000
Begin
UPDATE 商品_dmy SET 販売単価 = 販売単価 * 0.9
If (SELECT MIN(販売単価) FROM 商品_dmy) < 1000
Break -- 最低価格が1000円以下ならループを脱出
Else
Continue -- そうでなければ5%引きを繰り返す
End
上記(3)の「最低価格が1,000円未満になったら処理をやめる」という処理が、
If (SELECT MIN(販売単価) FROM 商品_dmy) < 1000
という条件判定となり、その結果が真(最低価格が1000未満)になったら
Break
を実行して、Whileによる繰り返し処理を抜けます。
実はこの場合、最後の
Else
Continue
は不要です。Ifの条件判定で結果がFalse(偽)になれば(最低価格が1000円以上なら)Breakが実行されずWhileループ終端のEndに達し、そのまま続けて繰り返し処理が実行されるためです。
ここでは、Continueの使用例として付け加えてみました。また、ソース自体は無駄な記述となっても、IfとElseの対応がはっきりしていた方が構造が分かりやすくなるため、特に長いソースでは、こういった冗長な記述をした方がよい場合もあります。
- プロシージャの実行 -
プロシージャを実行するには、以下のSQLを使います(ex07.sql)。
EXECUTE PriceDown2
実行すると、(35件処理されました)というメッセージが4回表示されるはずです。UPDATE命令による更新処理が4回実行され、最後の4回目を実行した後にIfによる条件判定の結果が「真」となったため、Breakで繰り返しを終えた──ということです。
《不要なプロシージャの削除》
前回と今回で作成した“YearlyTransfer3”“YearlyTransfer4”“PriceDown1”“PriceDown2”の4つのプロシージャは、特にデータベースに残しておく必要はありません。使わないプロシージャをたくさん保存しても無駄なので、動作を確かめた後で削除してもよいでしょう。
削除する場合は、クエリアナライザで以下の処理を実行してください。このソースはサンプルの「不要処理削除.sql」に保存されているため、それを開いて実行しても構いません。
もちろん、削除しないでそのまま残しておいても動作に支障はありません。
Drop Procedure YearlyTransfer3
Drop Procedure YearlyTransfer4
Drop Procedure PriceDown1
Drop Procedure PriceDown2 |
条件判断・分岐と繰り返しは制御構造の基本ですから、Visual BasicやC++などのプログラミング言語を知っている人なら、基本的な使い方はすぐに理解できるでしょう。
ただ、データベース・サーバーの側ではSQLを使ってデータセット(レコードセット)単位で処理を行うのが基本であるため、ストアドプロシージャでの繰り返しは「テーブルからレコードを1件ずつ取り出して……」といった形にはなりません。今回の例で取り上げたように同じテーブルに対して何度も更新処理を施したり、似たような名前のテーブルを連続削除するなど、特殊なケースが多くなります。
なおSQLには、処理を指定回数繰り返すFor(for)に該当する繰り返し命令は存在しません。
サンプルファイル (LZH形式
1.76KB)
|
|
|