Symfoware Parallel Server SQLビギナーズガイド
目次 索引 前ページ次ページ

第4章 カーソルを使用するデータ操作の方法

4.2 カーソルを宣言する

カーソルを使用してデータ操作を行うには、カーソルを宣言しておくことが必要です。カーソル宣言は非実行文です。カーソル宣言の指定位置は、そのカーソルを使用するSQL文よりも、応用プログラムの記述の順序で前にあることが必要です。実行順序とは関係ありません。

カーソル宣言の例を以下に示します。

例1

発注表から、取引先、取引製品、発注数量を求めるためのカーソルを宣言します。
DECLARE  発注表カーソル   CURSOR  FOR
             (1)

          SELECT 取引先, 取引製品, 発注数量 FROM 在庫管理.発注表
                                 (2)

(1) カーソル名

(2) 問合せ式

このカーソル宣言は、発注表から取引先、取引製品、および発注数量の3つの列の値を、すべての行について取り出すためのカーソルを宣言しています。

カーソルを使用して操作する表やデータの取り出し方は、カーソル宣言の問合せ式で指定します。例1の問合せ式で行うデータ操作は単純なものです。このカーソルを使用して表からデータを取り出し、応用プログラムの論理でいろいろな処理を行うことができます。一方、問合せ式では、表をグループ化して操作したり、複数の表の集合和からデータを取り出すことができます。問合せ式をうまく利用すれば、応用プログラムの処理を大幅に削減することが可能になります。

■問合せ

問合せ式には、1つの問合せ指定を指定する方法と、2つ以上の問合せ指定を“UNION”で結合して指定する方法があります。UNIONの指定方法については、“複数の表から行の集合和を求める”で説明します。

■問合せ指

問合せ指定は、単一行SELECT文からINTO句を取り除いたのと同じ形式です。問合せ指定により表を導出しますが、表の導出方法は単一行SELECT文の場合と同じです。すなわち、FROM句によって導出される表から、WHERE句の条件を満たす行について、選択リストで指定する列の値を取り出します。なお、単一行SELECT文では、取り出す行が2行以上あるとエラーになりますが、問合せ指定では、導出する行は何行あってもかまいません。

また、複数行を対象とするようなグループ処理ができます。詳しくは、“表をグループ化してデータを操作する”で説明します。ここでは、問合せ指定にGROUP BY句を使用したカーソル宣言について説明します。指定例を以下に示します。

例2

在庫表と発注表から、製品番号ごとの、製品名、発注している取引先の件数、および在庫数量と発注数量の合計を求めるためのカーソルを宣言します。

 

DECLARE 製品番号ごとに処理するカーソル CURSOR FOR 

    SELECT 製品番号, 製品名, COUNT(取引先), 在庫数量 + SUM(発注数量)

        FROM 在庫管理.在庫表, 在庫管理.発注表

        WHERE 製品番号 = 取引製品
         GROUP BY 製品番号, 製品名, 在庫数量
 

[図:カーソル表の導出]

■カーソルにより取り出す行の順

これまでに説明していないことで、1つ重要なことがあります。それは、カーソルによって取り出される行の順序に決まりはないということです。すなわち、カーソル表に含まれる行は問合せ式によって決定しますが、それらの行の順序についてはなにも決まっていません。このことは、1つの表からすべての行を取り出すような単純なカーソルでも同じです。“図:カーソル表の導出”で示したカーソル表の行は、たまたま製品番号の順番に並んでいますが、必ずしもこの順番

になるとは限りません。実際に応用プログラムを実行してみると、“図:カーソル表に含まれる行の順序は不定となる例”のような順序になるかもしれません。

[図:カーソル表に含まれる行の順序は不定となる例]


注1) COUNT(取引先)の結果から作成される列です。
注2) 在庫数量 + SUM(発注数量)の結果から作成される列です。
備考. 演算式や集合関数の結果の列には名前がありません。

■行の順序を並べ替え

カーソル宣言では、カーソル表に含まれる行を並べ替えることができます。カーソル表の行を並べ替えるには、問合せ式の後にORDER BYを指定します。なお、行を並べ替えることを“ソー”と呼びます。ORDER BY句の指定例を以下に示します。

例3

例2のカーソル宣言で、カーソルによってデータを取り出す順序を製品番号の小さい順とします。
DECLARE 製品番号ごとに処理するカーソル CURSOR FOR

      SELECT 製品番号, 製品名, COUNT(取引先), 在庫数量 + SUM(発注数量)

          FROM 在庫管理.在庫表, 在庫管理.発注表

          WHERE 製品番号 = 取引製品

          GROUP BY 製品番号, 製品名, 在庫数量

          ORDER BY  製品番号 ASC 
            (A)         (1)

(1) ソート指定

(A)〜(1) ORDER BY句

ORDER BY句には、ソートするための列名、集合関数または値式と、ソートの方法を指定します。ソートするための列を“ソートキ”と呼びます。ソートの方法には以下のどちらかが指定できます。なお、ソートの方法は省略することができ、その場合は“ASC”を指定したのと同じになります。

ASC:
値の小さい順に並べ替えます。“昇順ソー”といいます。
DESC:
値の大きい順に並べ替えます。“降順ソー”といいます。

 

例3のように指定することにより、カーソル表に含まれる行の順序は“図:カーソル表の導出”になることが決まります。なお、“図:カーソル表の導出”では製品番号の値は行ごとに異なっているので、カーソル表の行の順序は一意に決まりました。次に、製品番号の値が同じ行が複数あった場合について説明します。

同じソートキーの値が複数行ある場合には、それらの行間での順序に決まりはありません。ソートキーの値が異なる行間では、ソート指に従った順序となります。ソートキーの値が同じ行についても並べ替えるには、複数のソート指定をコンマ(,)で区切って指定します。ORDER BY句に指定された複数のソートキーは、左から順番に“第1ソートキー,第2ソートキー,…”と呼ばれます。カーソル表の行の順序は、まず第1ソートキーの値で並べ替えられ、その値が同じ行に対して第2ソートキーの値で並べ替えられます。すべてのソートキーについて同じ値を持つ行の順序には決まりはありません。指定例を以下に示します。

例4

在庫表から、倉庫番号の値の小さい順にデータを取り出すカーソルを宣言します。倉庫番号の値が同じ行については、在庫数量の値が大きい順とします。
DECLARE 在庫表カーソル CURSOR FOR

        SELECT * FROM 在庫管理.在庫表

            ORDER BY  倉庫番号  ASC,  在庫数量  DESC
             (C)         (1)    (A)      (2)     (B)

(1) 第1ソートキー

(2) 第2ソートキー

(1)〜(A)および(2)〜(B) ソート指定

(C)〜(B) ORDER BY句

[図:ソート指定を複数指定した例]

これまでは、カーソル表に含まれる列を使用して行の順序を並べ替える例について説明しましたが、カーソル表に含まれない列を使用してソートすることもできます。指定例を以下に示します。

例5

在庫表から、在庫数量が30未満の製品の製品番号と製品名を、在庫数量の値が大きい順にソートして取り出すカーソルを宣言します。

 

DECLARE 在庫数量カーソル CURSOR FOR

      SELECT 製品番号, 製品名 FROM 在庫管理.在庫表

         WHERE 在庫数量 < 30 ORDER BY 在庫数量 DESC
 

一方、問合せ指定の選択リストに演算式や、集合関数を指定した結果の列には名前がありません。名前のない列をソートキーにするには、ソート指定で列名の代わりに、列の番号を指定します。列の番号は、カーソル表の列を左から数えた順番です。指定例を以下に示します。

例6

例2のカーソル宣言で、カーソルによってデータを取り出す順序を、第1ソートキーを取引先の数で降順に、第2ソートキーを在庫数量と発注数量の合計で昇順にソートします。
DECLARE 製品番号ごとに処理するカーソル CURSOR FOR

      SELECT 製品番号, 製品名, COUNT(取引先), 在庫数量 + SUM(発注数量)

          FROM 在庫管理.在庫表, 在庫管理.発注表

          WHERE 製品番号 = 取引製品

          GROUP BY 製品番号, 製品名, 在庫数量

           ORDER BY  3  DESC,   4  ASC 
                        (1)      (2)

(1) 第1ソートキー

(2) 第2ソートキー

[図:ソート指定に列の番号を指定した例]

注1)  COUNT(取引先)の結果から作成される列です。
注2)  在庫数量 + SUM(発注数量)の結果から作成される列
        です。
備考.  演算式や集合関数の結果の列には名前がありません。

■更新可能カーソルと読込み専用カーソル

カーソルには、更新可能カーソと読込み専用カーソの2種類があります。カーソルを使用するUPDATE文やDELETE文は更新可能カーソルだけが使用できます。FETCH文は両方が使用できます。カーソルがどちらになるかは、カーソル宣言の指定の内容によって決まります。

読込み専用カーソルとなるカーソル宣言の条件を以下に示します。この例で使用する表TBL1および表TBL2のスキーマ名はSCMとします。

 

  1. DISTINCTを指定している。

    例:DECLARE CSR CURSOR FOR SELECT DISTINCT COLA, COLB FROM SCM.TBL1     
  2. 選択リスに演算式を指定している。

    例:DECLARE CSR CURSOR FOR SELECT COLC, COLA + COLB FROM SCM.TBL1
  3. 選択リストに集合関を指定している。

    例:DECLARE CSR CURSOR FOR SELECT SUM(COLB) FROM SCM.TBL1
  4. 選択リストに同じ列を指定している。

    例:DECLARE CSR CURSOR FOR
                SELECT COLA, COLB, COLA, COLC FROM SCM.TBL1
  5. 選択リストに定数またはホスト変を指定している。

    例:DECLARE CSR CURSOR FOR SELECT COLA, 100 FROM SCM.TBL1
  6. FROM句に2つ以上の表を指定している。

    例:DECLARE CSR CURSOR FOR SELECT COLA, COLZ FROM SCM.TBL1, SCM.TBL2
  7. GROUP BY句またはHAVING句を指定している。

    例:DECLARE CSR CURSOR FOR SELECT COLA FROM SCM.TBL1 GROUP BY COLA
  8. WHERE句に副問合を含んでいる。

    例:DECLARE CSR CURSOR FOR SELECT * FROM SCM.TBL1
             WHERE COLA IN (SELECT COLZ FROM SCM.TBL2 WHERE COLY > 2000)  
  9. UNIONを指定している。

    例:DECLARE CSR CURSOR FOR                                                
               SELECT COLC FROM SCM.TBL1 UNION SELECT COLX FROM SCM.TBL2  
  10. 更新可能性にFOR READ ONLYを指定している。

    例:DECLARE CSR CURSOR FOR
                SELECT COLA, COLB FROM SCM.TBL1 FOR READ ONLY
  11. ORDER BY句を指定し、更新可能性句を指定していない。

    例:DECLARE CSR CURSOR FOR
                SELECT COLA, COLB FROM SCM.TBL1 ORDER BY COLA

カーソル宣言の形式が、a)からk)のいずれかに該当する場合、読込み専用カーソルになります。いずれにも当てはまらない場合は、更新可能カーソルになります。

a)からh)は、問合せ指定で指定する要素です。また、i)は問合せ式で指定する要素です。j)からk)は、カーソル宣言で指定する要素です。k)は、更新可能性句にFOR UPDATEを指定したときのみ更新可能カーソルとなります。なお、h)の副問合せについては“いろいろな探索条件を指定する”を、i)のUNIONについては“複数の表から行の集合和を求める”をそれぞれ参照してください。


目次 索引 前ページ次ページ

All Rights Reserved, Copyright(C) 富士通株式会社 2006