制御構造には、前回紹介した条件判断と分岐のIf~Elseの他、繰り返し処理を行うWhileがあります。まずは基本を知っておきましょう。
- 条件が「真」の間繰り返す -
Whileの書式は以下のようになります。
While <論理式>
Begin
<処理>
End
<論理式>とは真(True)または偽(False)を返す式で、一般には表1に示す比較演算子を用いて記述します。また、比較演算子を用いた式同士を表2に示す論理演算子で結ぶこともできます。比較演算子も論理演算子も、式を評価した結果が正しければTrue、正しくなければFalseを返します。
Whileは、<論理式>がTrueである間、Begin~End間の<処理>を繰り返します。<処理>を1回実行するたびに<論理式>を評価し、その結果が偽(False)になった時点で繰り返しをやめて、Endの次の処理に移ります。これを(ループを)「抜ける」あるいは「脱出する」と表現します。
表1:比較演算子
演算子 |
意味 |
= |
記号の左右の値が等しい |
> |
記号の左が右より大きい |
< |
記号の左が右より小さい |
>= |
記号の左が右以上 |
<= |
記号の左が右以下 |
<> |
記号の左右の値が等しくない |
!= |
記号の左右の値が等しくない★ |
!< |
記号の左が右より小さくない(記号の左が右以上)★ |
!> |
記号の左が右より大きくない(記号の左が右以下)★ |
【注意】★マークを付けた「!」を使った演算子はSQL-92に準拠していません
表2:論理演算子
演算子 |
意味 |
AND |
双方の条件式がTrueの場合にTrueを返す |
OR |
どちらかまたは双方の条件式がTrueの場合にTrueを返す |
NOT |
論理値を反転(TrueをFalseに、FalseをTrueに)する |
- 単価を段階的に割り引く -
Whileを使った単純な例を紹介しておきましょう。
販売単価が8,000円を超える高額商品が増えてきたため、商品の価格を見直すことになりました。これらの高額商品を値下げしようと思うのですが、どの程度値下げすればよいか一律には決められません。
まず、以下のSQLを実行すれば、販売単価が8,000円以上の商品が11件あることが分かります。
SELECT COUNT(商品ID) FROM 商品_mr WHERE 販売単価 >=8000
そこで、これら高額商品の販売単価を5%ずつ減額していき、8,000円以上の高額商品が5件以下になるよう調整するとどうなるか──シミュレーションすることになりました。
上記のようなシミュレーションを実行するには、以下のような処理が必要になります。
まず、テーブル「商品_mr」を直接書き換えてはいけないので、ダミーのテーブル「商品_dmy」を使うことにします。
(1)繰り返し処理開始
(2)販売単価が8,000円を超える商品が5件になったら処理をやめる -- 脱出条件
(3)販売単価が8,000円を超える商品の販売単価を5%引きにする
(4)繰り返し処理終わり
- SELECT文を条件にする -
上のような処理を実現するには、以下のようなソースを記述します。プロシージャ名を“PriceDown1”としています(ex04.sql)。
Create Procedure PriceDown1
As
While (SELECT COUNT(商品ID) FROM 商品_dmy WHERE 販売単価 >=8000) > 5
Begin
UPDATE 商品_dmy SET 販売単価 = 販売単価 * 0.95 WHERE 販売単価 >=8000
End
Whileに続く以下の部分が繰り返しの条件です。
(SELECT COUNT(商品ID) FROM 商品_dmy WHERE 販売単価 >=8000) > 5
SELECT命令にCOUNT集計関数を使って、販売単価が8000以上のレコード件数(「商品ID」に値の入っている件数)を取得し、それが5より多いときだけ処理を繰り返します。アンダーラインの箇所の「> 5」が比較演算子を使った条件式で、この評価結果がTrueである間だけ続く処理が繰り返されます。
その直前にある「WHERE 販売単価 >=8000」という条件式は、SELECT命令でレコード件数を取得するためのものです。
なお、While命令にSELECT命令によるSQL文を与える場合は、SELECT文全体(上の例では“>=8000”まで)を( )で囲まなければなりません。
【注意】
冒頭にも書いたように、この処理はテーブルの値(「販売単価」フィールドの値)を書き換えるため、必ず「商品_dmy」テーブルを使ってください。
- 更新処理を繰り返す -
繰り返される処理は、Begin~Endで囲んだ以下のSQL文です。
UPDATE 商品_dmy SET 販売単価 = 販売単価 * 0.95 WHERE 販売単価 >=8000
処理が1行で済む場合には特にBegin~Endで囲む必要はありませんが、ここでは分かりやすくするために囲んでいます。
このSQL文は、単純に
販売単価が8000円以上のレコードに対して
一律に販売単価を5%引き(0.95倍)する
という処理を実行します。
この処理を、最初の条件に設定した「販売単価が8,000円を超える商品が5件より大きい間」繰り返すことになります。
- プロシージャの実行 -
実行には、EXECUTE命令を使います(ex05.sql)。
EXECUTE PriceDown1
とすれば、クエリアナライザの「メッセージ」ペインには画面2のように延々と処理件数が表示され、やがて処理は終わります。UPDATE命令で5%の値下げ処理を繰り返しているため、処理件数が次第に減っているのが分かります。レコードが5件以下になれば処理は終わるため、(6件処理されました)のメッセージが何度か表示されて処理は終了します。
このようにWhile命令は、SQL文による処理を何度も繰り返したいときに用います。レコードを1件ずつ処理するのではなく、レコード全体(データセット)に対する処理を繰り返す――という点に注意しましょう。
テーブルからレコードを1件ずつ取り出して処理を行うなら、アプリケーションのレベルで繰り返し構造(プログラミング言語のForやWhile)を使うことになります。ストアドプロシージャの繰り返し処理は、UPDATEやINSERTなどテーブルの内容を一括して書き換えるような処理に対して用います。
|
|
|