ページの先頭行へ戻る
Symfoware Server V11.0.x SQLリファレンス
Symfoware

3.26 DECLARE CURSOR(カーソル宣言)

機能

カーソルを定義します。

カーソルとは

ホスト言語プログラムは、表の複数行を一度に取り出して処理することはできません。これを解決するために、複数行のうちの1行をホストプログラムから、参照したり更新したりすることができるようにする手段としてカーソルがあります。カーソルは、一連の流れに対応したSQL文を使用して処理します。カーソルの使用方法を以下に示します。

  • カーソルはカーソル宣言(DECLARE CURSOR)で、問合せ式を指定して行の集合を宣言します。

  • カーソルをOPEN文で開くことにより、問合せ式の結果である行の集合から1行を取り出す準備ができます。

  • 複数回のFETCH文の実行により、複数行をホストプログラムに取り出すことができます。

  • FETCH文で取り出した行をUPDATE文:位置づけで更新したり、DELETE文:位置づけで削除したりすることができます。

  • 最終行まで処理したカーソルは、CLOSE文により閉じます。

カーソルはOPEN文によって開かれた状態になり、FETCH文により次の行に移動していきます。カーソルの位置は、SQL文の実行により以下のように移動します。

図3.1 SQL文の実行によるカーソル位置の移動

あるカーソルと別のカーソルのカーソル指定に同じ表を指定した場合、または、あるカーソルのカーソル指定に指定した表と同じ表を非カーソル系のSQL文に指定した場合、先行するそのカーソルの操作によっては、後続の操作(別のカーソルによる操作、または非カーソル系のSQL文の実行)が不可能な場合があります。ただし、ここでいう表とは、SQL文に指定した表がビュー表の場合、そのビュー表に含まれる表のことです。この関係を以下に示します。

表3.8 同一の表に複数のカーソル系のSQL文または非カーソル系のSQL文でアクセスした場合の実行結果

  

後続操作

カーソル系

非カーソル系

参照

更新

参照

更新

OPEN
CSR2

UPDATE
・・・
CSR2

DELETE
・・・
CSR2

SELECT
・・・
FROM T1

INSERT
INTO
・・・
SELECT
FROM T1

INSERT
INTO T1

・・・

UPDATE
T1
・・・

DELETE
FROM T1

・・・

先行操作

カーソル系

参照

OPEN
CSR1

× (注1)

× (注2)

更新

UPDATE
・・・
CSR1

× (注3)

× (注4)

× (注5)

DELETE
・・・
CSR1

○: 後続する操作は実行可能です。

×: 後続する操作は実行できません。

注1) 表T1を参照するカーソルCSR1をオープン後、カーソルCSR2により表T1を更新すると、次にカーソルCSR1のFETCH文で表T1の行を取り出すときに、更新前の状態で取り出されることと、更新後の状態で取り出されてしまうことがあります。このためカーソルCSR2による表T1の更新は、カーソルCSR1をクローズしてから実行してください。

注2) 表T1を参照するカーソルCSR1をオープン後、非カーソル系のSQL文により表T1の行を更新すると、次にカーソルCSR1のFETCH文で表T1の行を取り出すときに、更新前の状態で取り出されることと、更新後の状態で取り出されてしまうことがあります。このため非カーソル系のSQL文による表T1の更新は、カーソルCSR1をクローズしてから実行してください。

注3) カーソルCSR1により表T1を更新後、カーソルCSR2をオープンすると、次にカーソルCSR2のFETCH文で表T1の行を取り出すときに、更新前の状態で取り出されることと、更新後の状態で取り出されてしまうことがあります。このためカーソルCSR2のオープンは、カーソルCSR1をクローズしてから実行してください。なお、カーソルCSR1により表T1を更新後、カーソルCSR2で表T1を更新すると、データベースとカーソルの間で矛盾を起こすことがあります。

注4) カーソルCSR1により表T1を更新後、非カーソル系のSQL文で表T1を参照すると、更新前の状態で参照されることと、更新後の状態で参照されてしまうことがあります。このため非カーソル系のSQL文による表T1の参照は、カーソルCSR1をクローズしてから実行してください。

注5) カーソルCSR1により表T1を更新後、非カーソル系のSQL文で表T1を更新すると、次にカーソルCSR1のFETCH文で表T1の行を取り出すときに、データベースとカーソルの間で矛盾を起こすことがあります。このため非カーソル系のSQL文による表T1の更新は、カーソルCSR1をクローズしてから実行してください。

備考.カーソルCSR1とカーソルCSR2のカーソル宣言は、両方とも表T1を指定したとします。

記述形式

構文の構成

参照項番

一般規則

カーソル名
  • カーソル名は、カーソルの名前を指定します。

  • カーソル名には、36文字以内の先頭が英字で始まる英数字、または18文字以内の日本語文字列を指定します。

SCROLL
  • FETCH文に取出し方向を指定する場合、カーソル宣言にSCROLLの指定が必要です。ただし、取出し方向にNEXTを指定した場合は、SCROLLの指定を省略することができます。

  • 問合せ式で選択リストに、格納構造がOBJECTでBLOB型の列が指定された場合は、SCROLLは指定できません。

  • プロシジャルーチン定義中にSCROLLは指定できません。

問合せ指定
  • 問合せ指定は、表式の結果から導出される表を指定します。

  • 問合せ指定の結果を以下に示します。

    • 表式の結果がグループ表でない場合、問合せ指定の結果は次のようになります。選択リストに集合関数指定がない場合、表式の結果の各行に選択リストの値式で示す演算が行われた、行の集合となります。選択リストに集合関数の指定がある場合の結果は、表式の結果を集合関数に適用した1行となります。

    • 表式の結果がグループ表の場合、問合せ指定の結果は次のようになります。結果の行の数はグループの数となります。各行の値は、選択リストに集合関数の指定がある場合には、グループを集合関数に適用した結果となり、列指定の場合には、グループ化列の値となり、グループ化関数の場合は、グループ化関数の値となります。なお、選択リストにGROUP BY句のAS句の列名を指定した場合は、対応するグループ化列、グループ化関数またはCASE式の値となります。

    • 表式の結果が空であれば、問合せ指定の結果は、空の表となります。

DISTINCTおよびALL
  • DISTINCTは、問合せ指定の結果の各行同士がまったく同じ値を持つ行がある場合、それらの行を1行とする処理が行われます。このとき、NULL値同士は等しいとみなされます。ALLは、重複行をそのまま残す場合に指定します。また、どらちも省略した場合は、ALLが指定されたものとみなします。

  • 問合せ式で選択リストに、BLOB型の列が指定された場合は、DISTINCTは指定できません。

  • 問合せ式で選択リストに、順序が指定された場合は、DISTINCTは指定できません。

選択リスト
  • 選択リストには、表式の結果から導出される表の列を指定します。

  • 選択リストに“*”を指定した場合、FROM句で指定した順に各表の各列のすべてを記述したのと同じ意味です。

  • 選択副リストは、選択リストにカンマ(,)で区切って指定する1つ1つの要素です。

  • 選択リストに“表名.*”または“相関名.*”が指定された場合、表のすべての列を記述したのと同じ意味です。“表名.”と“相関名.”は“修飾子”と呼びます。

  • 選択リスト中に含まれる列指定は、FROM句で指定した表の列またはGROUP BY句のAS句の列名であることが必要です。

  • 選択リストに格納構造がOBJECTのBLOB型の列を複数指定することはできません。

  • 表式の結果がグループ表の場合、選択リストの列指定は、グループ化列またはGROUP BY句のAS句の列名を指定するか、集合関数指定またはグループ化関数の引数で指定することが必要です。

  • 表式の結果がグループ表でなく、選択リストに集合関数を指定する場合は、選択リストのすべてが集合関数指定であることが必要です。

  • 選択リストにAS句が指定された場合、選択リストの結果の列名はAS句に指定された列名となります。

  • AS句の列名はORDER BY句のソート指定に列名として指定することができます。

FROM
  • FROM句は、1つ以上の名前付きの表や問合せ指定の結果から導出される表(導出表)または結合表を指定します。FROM句に指定する表、導出表または結合表を表参照といいます。

  • FROM句の結果は、次のとおりです。

    • FROM句で指定される表が1つならば、FROM句の結果は、その表となります。

    • FROM句で指定される表が複数ならば、FROM句の結果は、それらの表の拡張直積となります。拡張直積は、指定された複数の表の列と行のすべてを組み合わせて導出します。拡張直積により導出される表の列数は、元となる表の列数の総和となります。列の順序は、指定された表の列の順序となります。また、表の行数は、元となる表の行数の積となります。

例1

問合せ指定のFROM句に表TBL1と表TBL2の2つの表を指定した例です。

SELECT COL1,BCOL FROM TBL1,TBL2

FROM句の結果は、表TBL1と表TBL2の拡張直積となります。


例2

問合せ指定のFROM句に結合表を指定した例です。結合する表をそれぞれT1、T2とし、探索条件を“T1.C1=T2.C4”とします。

表名
  • 検索対象とする表の名前を指定します。

相関名
  • 相関名は、表の別名を指定します。

  • 相関名には、36文字以内の先頭が英字で始まる英数字、または18文字以内の日本語文字列を指定します。

  • 相関名が指定されていない表名は、ほかの相関名が指定されていない表名と同じであってはいけません。

  • 相関名は、相関名指定のない表名と同じであってはいけません。また、ほかの相関名と同じであってはいけません。

  • FROM句の中に指定される相関名と、相関名が指定されない表名の有効範囲は、FROM句が含まれる表式を含む最も内側の問合せ指定または副問合せになります。

    (1) 表名T1の有効範囲

    (2) 相関名X1の有効範囲

    (3) 相関名X2の有効範囲

    (4) 表名T3の有効範囲


導出表
  • 導出表の問合せ指定が読込み専用ならば、導出表は読込み専用の表になります。問合せ指定が更新可能ならば、導出表は更新可能な表になります。問合せ指定が読込み専用または更新可能になる条件については、“表3.12 読込み専用カーソルとなる条件”を参照してください。

  • 導出列リストは、導出表の列の別名を指定します。導出表の問合せ指定の選択リストに以下の条件を1つでも満たす値式を指定した場合、導出列リストは省略できません。

    • 列指定以外を指定した場合

    • 同じ列名を複数指定した場合

  • 導出列リストは、列名をカンマで区切り括弧でくくって指定します。

  • 導出表の問合せ指定の選択リストの個数と、導出列リストの列名の個数は同じであることが必要です。

  • 導出列リストに記述できる列名の数は、最大32000個です。

  • 導出表の選択リストに順序を指定することはできません。

  • 導出表を記述したSQL文を実行した場合、Symfoware/RDBの最適化処理で入れ子をなくし平坦な形式のSQL文に変換する場合があります。このSQL文の変換では、変換前のSQL文の導出表の選択リストにCAST指定が指定されていると、CAST指定を条件式に移動することがあります。このとき、データベースにCAST指定で変換できないデータが含まれると、導出表の条件式において変換できないデータを除外していたとしても、条件式に移動したCAST指定において、CAST指定の変換エラーが発生する場合があります。そのため、データベースにCAST指定で変換できないデータが含まれる場合は、CASE式を用いて、変換できないデータを除外することにより、CAST指定で変換エラーが発生しないように対処してください。
    以下に例を示します。

    実行するSQL文

    注1) 選択リストにCAST指定を記述。

    注2) 最も内側の導出表にて文字列の空白以外を取り出す判定。

    最適化処理が変換したSQL文

    Symfoware/RDBの最適化処理が変換したSQL文は、以下のようになります。

    注1) 文字列の空白以外を取り出す判定。

    注2) 文字列をCASTし、変換結果を判定。

    その結果、注2のCAST指定に指定された列の値が空白の場合、TIMESTAMP型にデータ型変換することができず、変換エラーになります。

    対処例

    CASE式を用いて、空白のデータを除外することにより、CASTで変換エラーが発生しないように対処してください。

結合表(OUTER JOIN)
  • 結合型は、結合表で結合の方法を示すものです。

  • LEFTを指定した場合は、左側の表の列の値にない右側の表の列の値をNULL値に置き換えた行となります。

  • RIGHTを指定した場合は、右側の表の列にない値と左側の表の列の値をNULL値に置き換えた行となります。

  • 左側の表と右側の表には、以下のいずれも指定することはできません。

    • 同じ名前の表名(相関名を指定しない)

    • 同じ名前の相関名

  • 左側の表または右側の表に相関名を指定する場合、結合表における相関名が指定されていない表名と同じであってはいけません。

  • 探索条件中に直接含まれる列は、表参照で指定した列であることが必要です。

  • 探索条件に副問合せは指定できません。

  • 探索条件にROWNUMは指定できません。

  • 結合表は、読込み専用の表であり、更新することはできません。

WHERE
  • WHERE句は、導出される表に対して探索条件を指定します。

  • 探索条件に指定した列指定は、FROM句に指定した表の列を指定するか、または外への参照であることが必要です。

    外への参照は“2.4 列指定”を参照してください。

  • WHERE句の結果は、FROM句の結果の表に対して、探索条件を適用した結果が真の行からなる表です。

  • 探索条件に順序は指定できません。

  • 探索条件に指定した値式が集合関数指定ならば、その探索条件は、HAVING句に指定された副問合せのWHERE句に指定したものであることが必要です。なお、集合関数指定の中の列指定は、外への参照であることが必要です。以下に例を示します。

    SELECT C11,AVG(C12)
        FROM T1
        GROUP BY C11
        HAVING AVG(C12) < (SELECT COUNT(C21)
                           FROM T2
                           WHERE SUM(T1.C12) < T2.C22)

FROM句に指定された結果にWHERE句を適用することによって、必要な行だけを絞り込んだ表を導出します。

SELECT COL1,BCOL
    FROM TBL1,TBL2
    WHERE COL2 = ACOL

表TBL1と表TBL2の拡張直積からWHERE句の条件を満たす行が絞り込まれます。


GROUP BY
  • GROUP BY句は、導出された表に対してグループ化するための条件を指定(グループ化指定と呼びます)します。

  • GROUP BY句に列指定を指定した場合、その列をグループ化列といいます。

  • GROUP BY句にデータ列値関数、数値関数または日時値関数を指定した場合、その関数をグループ化関数といいます。

  • GROUP BY句に指定する関数は、CURRENT DATE値関数、CURRENT TIME値関数、CURRENT TIMESTAMP値関数であってはいけません。

  • GROUP BY句の結果は、指定したグループ化列、関数およびCASE式の値が同一の行の集まりを1つのグループとした、グループの集まりからなる表です。

  • GROUP BY句に、グループ化関数を指定する場合、その関数中に指定する値式は、以下の条件を満たすことが必要です。

    • 関数内に指定する値式には、値指定、列指定、数値式、データ列値式、日時値式および時間隔値式を指定することができます。

    • 関数内に指定する値式には、集合関数、外への参照の列および動的パラメタ指定を指定することはできません。

    • 関数内に指定する値式には、列指定を必ず含むことが必要です。

  • 列指定は、FROM句に指定した表の列であることが必要です。

  • GROUP BY句を指定した場合、HAVING句および問合せ指定の選択リストに指定する値式は、以下のいずれかでなければなりません。

    • 値指定

    • 集合関数

    • CURRENT DATE値関数、CURRENT TIME値関数、CURRENT TIMESTAMP値関数

    • グループ化列

    • AS句の列名

    • グループ化列またはAS句の列名を含む値式。ただし、値式に含まれるすべての列指定がグループ化列またはAS句の列名でなければなりません。

    • グループ化関数

  • HAVING句および問合せ指定の選択リストにグループ化関数を指定する場合、以下の注意が必要です。

    • 値式の引数にグループ化関数を指定する場合、グループ化関数の引数に指定する列指定は、すべてグループ化列またはAS句の列名でなければなりません。また、副問合せ内で、グループ化関数の引数に外への参照の列指定を指定する場合、グループ化関数の引数に指定する列指定は、すべてグループ化列またはAS句の列名でなければなりません。

  • 集合関数の引数にグループ化関数を指定することはできません。

  • グループ化指定に、CASE式を指定する場合、そのCASE式中に指定する値式は以下の条件を満たすことが必要です。

    • CASE式内に指定する値式には、集合関数、外への参照の列および動的パラメタ指定を指定することはできません。

    • CASE式内に指定する値式には、列指定を必ず含むことが必要です。

  • AS句の列名をHAVING句や問合せ指定の選択リストに指定した場合は、AS句の列名に対応する列指定、関数またはCASE式が指定されたものとみなされます。

  • グループ化指定に指定したCASE式をそのままHAVING句や問合せ指定の選択リストに指定しても、グループ化したCASE式とはみなされません。CASE式を指定する場合は、AS句の列名を使用してください。

  • AS句の列名は、FROM句の表の列名と同じであってはいけません。また、GROUP BY句において一意でなければなりません。

  • AS句の列名を値式として指定する場合には以下の規約があります。

    • 外への参照でない場合、HAVING句、選択リスト、ORDER BY句以外に指定することはできません。

    • 外への参照の場合、結合表の結合条件、WHERE句、HAVING句以外に指定することはできません。また、AS句の列名を含む副問合せが、HAVING句に含まれていなければなりません。

  • GROUP BY句にはBLOB型の列は指定できません。

  • GROUP BY句にROWNUMは指定できません。

問合せ指定にFROM句、WHERE句およびGROUP BY句を適用した例を示します。

SELECT SUM(COL1),BCOL
    FROM TBL1,TBL2
    WHERE COL2 = ACOL
    GROUP BY BCOL

表TBL1と表TBL2の拡張直積からWHERE句の条件を満たす行が絞り込まれます。さらに、GROUP BY句で指定された列の値が同一の行を1つのグループとします。この結果、問合せ指定の結果が2件となります。

注) 集合関数の結果の列には名前がありません。


HAVING
  • HAVING句は、GROUP BY句またはFROM句の結果であるグループ表に対し、探索条件に合うグループだけを選びだす条件を指定します。

  • 探索条件に含まれる列指定は、FROM句で指定した表の列またはGROUP BY句のAS句の列名であることが必要です。

  • 探索条件に含まれる列指定は、グループ化列またはGROUP BY句のAS句の列名を指定するか、集合関数指定またはグループ化関数の引数で指定することが必要です。

  • 探索条件に含まれる列指定が外への参照の場合、副問合せが指定される句がWHERE句か、HAVING句かにより、指定のしかたが異なります。以下に外への参照の指定のしかたについて示します。外への参照は、“2.4 列指定”を参照してください。

    • WHERE句に指定した副問合せの場合、副問合せのHAVING句の外への参照は直接の列指定であることが必要です。以下にWHERE句に指定した副問合せにHAVING句を指定した例を示します。

      SELECT C11,C12
      FROM T1
      WHERE T1.C13 = (SELECT SUM(C22) FROM T2
                      GROUP BY C21
                      HAVING T2.C21 = T1.C14)
                                        (1)

      (1) 列指定

    • HAVING句に指定した副問合せの場合、副問合せのHAVING句に指定する外への参照は、グループ化列またはGROUP BY句のAS句の列名を直接指定するか、またはグループ化列またはGROUP BY句のAS句の列名以外を集合関数で指定する必要があります。

  • HAVING句の結果は、GROUP BY句の結果のグループ表に対して、探索条件を適用した結果が真の行からなるグループ表です。以下にHAVING句に指定した副問合せにHAVING句を指定した例を示します。

    SELECT C11,AVG(C12)
    FROM T1
    GROUP BY C11
    HAVING AVG(C13) = (SELECT SUM(C22) FROM T2
                       GROUP BY C21
                       HAVING T2.C21 = T1.C11 AND AVG(T2.C22) = AVG(T1.C12))
                               (1)                  (2)

    (1) 列指定

    (2) 集合関数指定

  • 探索条件にROWNUMは指定できません。

例1

HAVING句にグループ化列と集合関数を指定した例です。

SELECT COL2,SUM(COL3)
FROM T1
GROUP BY COL2
HAVING COL2 = N'冷蔵庫' AND AVG(COL3) < 40
        (1)                    (2)

(1) グループ化列

(2) 集合関数指定

注) 集合関数の結果の列には名前がありません。


例2

“GROUP BY句”で示した例にHAVING句を追加した例を示します。

SELECT SUM(COL1),BCOL
FROM TBL1,TBL2
WHERE COL2 = ACOL
GROUP BY BCOL
HAVING COUNT(*) > 1

表TBL1と表TBL2の拡張直積からWHERE句の条件を満たす行が絞り込まれます。そして、GROUP BY句で指定された列の値が同一の行を1つのグループとします。さらに、HAVING句でグループが限定されます。この結果、問合せ指定の結果は1件となります。

注) 集合関数の結果の列には名前がありません。


問合せ式(UNION)
  • UNIONを指定すると、問合せ式の結果は、左辺と右辺の表の集合演算を行った表となります。UNIONを“集合演算子”と呼びます。集合演算の結果は次のようになります。

    • ALLを指定すると、左辺と右辺の表の集合和となります。

    • ALLを指定しないと、ALLを指定した結果の各行同士に、まったく同じ値を持つ行がある場合、それらの複数行を1行とする処理が行われます。このとき、NULL値同士は等しいとみなされます。

  • 問合せ項は、問合せ式を構成する1つの要素です。

  • 集合演算子は、括弧を優先し、左から右に適用されます。

  • 問合せ式にUNIONを含む場合、集合演算の結果の表は一番左側の問合せ指定の列名になります。

  • 集合演算子UNIONを指定する場合、集合演算の対象となるそれぞれの問合せ指定は、以下の条件を満たすことが必要です。

    • 選択リストの結果の個数は同じであることが必要です。

    • 選択リストの結果の集合演算で対応する列同士は、比較可能であることが必要です。比較可能なデータ型に関する規則は、“表2.58 比較可能なデータ型”を参照してください。

  • 最終結果に採用されるデータ型の一覧を“表3.9 集合演算(UNION)におけるデータ変換”、“表3.10 時間隔型(YEAR,MONTH)の集合演算(UNION)におけるデータ変換”および“表3.11 時間隔型(DAY,HOUR,MINUTE,SECOND)の集合演算(UNION)におけるデータ変換”に示します。

    表3.9 集合演算(UNION)におけるデータ変換

    集合演算対象のデータ型

    集合演算結果のデータ型

    1項

    2項

    SMALLINT

    SMALLINT

    SMALLINT(無変換)

    INTEGER

    INTEGER

    DECIMAL(p,q)

    DECIMAL(r,s)
    r: MIN(18,MAX(p-q,5)+q)
    s: q

    NUMERIC(p,q)

    REAL

    REAL

    DOUBLE PRECISION

    DOUBLE PRECISION

    INTEGER

    SMALLINT

    INTEGER

    INTEGER

    INTEGER(無変換)

    DECIMAL(p,q)

    DECIMAL(r,s)
    r: MIN(18,MAX(p-q,10)+q)
    s: q

    NUMERIC(p,q)

    REAL

    REAL

    DOUBLE PRECISION

    DOUBLE PRECISION

    DECIMAL(p1,q1)

    SMALLINT

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,5)+q1)
    s: q1

    INTEGER

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,10)+q1)
    s: q1

    DECIMAL(p2,q2)

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,p2-q2)+MAX(q1,q2))
    s: MAX(q1,q2)

    NUMERIC(p2,q2)

    REAL

    REAL

    DOUBLE PRECISION

    DOUBLE PRECISION

    NUMERIC(p1,q1)

    SMALLINT

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,5)+q1)
    s: q1

    INTEGER

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,10)+q1)
    s: q1

    DECIMAL(p2,q2)

    DECIMAL(r,s)
    r: MIN(18,MAX(p1-q1,p2-q2)+MAX(q1,q2))
    s: MAX(q1,q2)

    NUMERIC(p2,q2)

    REAL

    REAL

    DOUBLE PRECISION

    DOUBLE PRECISION

    REAL

    SMALLINT

    REAL

    INTEGER

    REAL

    DECIMAL(p,q)

    REAL

    NUMERIC(p,q)

    REAL

    REAL

    REAL(無変換)

    DOUBLE PRECISION

    DOUBLE PRECISION

    DOUBLE PRECISION

    SMALLINT

    DOUBLE PRECISION

    INTEGER

    DOUBLE PRECISION

    DECIMAL(p,q)

    DOUBLE PRECISION

    NUMERIC(p,q)

    DOUBLE PRECISION

    REAL

    DOUBLE PRECISION

    DOUBLE PRECISION

    DOUBLE PRECISION(無変換)

    CHAR(n1)

    CHAR(n2)

    CHAR(m) m: MAX(n1,n2)

    VARCHAR(n2)

    VARCHAR(m) m: MAX(n1,n2)

    VARCHAR(n1)

    CHAR(n2)

    VARCHAR(m) m: MAX(n1,n2)

    VARCHAR(n2)

    VARCHAR(m) m: MAX(n1,n2)

    NCHAR(n1)

    NCHAR(n2)

    NCHAR(m) m: MAX(n1,n2)

    NCHAR VARYING(n2)

    NCHAR VARYING(m) m: MAX(n1,n2)

    NCHAR VARYING(n1)

    NCHAR(n2)

    NCHAR VARYING(m) m: MAX(n1,n2)

    NCHAR VARYING(n2)

    NCHAR VARYING(m) m: MAX(n1,n2)

    DATE

    DATE

    DATE

    TIME

    TIME

    TIME

    TIMESTAMP

    TIMESTAMP

    TIMESTAMP

    INTERVAL

    INTERVAL

    INTERVAL (注)

    注) 集合演算結果のデータ型の詳細については、表3.10 時間隔型(YEAR,MONTH)の集合演算(UNION)におけるデータ変換および表3.11 時間隔型(DAY,HOUR,MINUTE,SECOND)の集合演算(UNION)におけるデータ変換を参照してください。


    表3.10 時間隔型(YEAR,MONTH)の集合演算(UNION)におけるデータ変換

      

    2項

    YEAR(p2)

    YEAR(p2) TO MONTH

    MONTH(p2)

    1項

    YEAR(p1)

    YEAR(p)
    p: MAX(p1,p2)

    YEAR(p) TO MONTH
    p: MAX(p1,p2)

    YEAR(p) TO MONTH
    p: MIN(9,
    MAX(p1,p2-1))

    YEAR(p1) TO MONTH

    YEAR(p) TO MONTH
    p: MAX(p1,p2)

    YEAR(p) TO MONTH
    p: MAX(p1,p2)

    YEAR(p) TO MONTH
    p: MIN(9,
    MAX(p1,p2-1))

    MONTH(p1)

    YEAR(p) TO MONTH
    p: MIN(9,
    MAX(p1-1,p2))

    YEAR(p) TO MONTH
    p: MIN(9,
    MAX(p1-1,p2))

    MONTH(p)
    p: MAX(p1,p2)

    p、p1、p2: 時間隔先行フィールド精度


    表3.11 時間隔型(DAY,HOUR,MINUTE,SECOND)の集合演算(UNION)におけるデータ変換

      

    2項

    DAY(p2) TO E2

    HOUR(p2) TO E2

    MINUTE(p2) TO E2

    SECOND(p2)

    1項

    DAY(p1) TO E1

    DAY(p) TO E
    p: MAX(p1,p2)
    E: MIN(E1,E2)

    DAY(p) TO E
    p: MIN(9,
    MAX(p1,p2-1))
    E: MIN(E1,E2)

    DAY(p) TO E
    p: MIN(9,
    MAX(p1,p2-3))
    E: MIN(E1,E2)

    DAY(p) TO SECOND
    p: MIN(9,
    MAX(p1,p2-5))

    HOUR(p1) TO E1

    DAY(p) TO E
    p: MIN(9,
    MAX(p1-1,p2))
    E: MIN(E1,E2)

    HOUR(p) TO E
    p: MAX(p1,p2)
    E: MIN(E1,E2)

    HOUR(p) TO E
    p: MIN(9,
    MAX(p1,p2-1))
    E: MIN(E1,E2)

    HOUR(p) TO SECOND
    p: MIN(9,
    MAX(p1,p2-3))

    MINUTE(p1) TO E1

    DAY(p) TO E
    p: MIN(9,
    MAX(p1-3,p2))
    E: MIN(E1,E2)

    HOUR(p) TO E
    p: MIN(9,
    MAX(p1-1,p2))
    E: MIN(E1,E2)

    MINUTE(p) TO E
    p: MAX(p1,p2)
    E: MIN(E1,E2)

    MINUTE(p) TO SECOND
    p: MIN(9,
    MAX(p1,p2-1))

    SECOND(p1)

    DAY(p) TO SECOND
    p: MIN(9,
    MAX(p1-5,p2))

    HOUR(p) TO SECOND
    p: MIN(9,
    MAX(p1-3,p2))

    MINUTE(p) TO SECOND
    p: MIN(9,
    MAX(p1-1,p2))

    SECOND(p)
    p: MAX(p1,p2)

    p、p1、p2: 時間隔先行フィールド

    E、E1、E2: 日時フィールド

    なお、日時フィールドには以下の大小関係があります。

    DAY > HOUR > MINUTE > SECOND

MIN(DAY,MINUTE) = MINUTE

カーソル指定
  • カーソル指定で導出される表は、カーソルの定義方法によって、更新可能または読込み専用となります。カーソル指定で導出される表の扱いは次のとおりです。

    • カーソル指定の問合せ式が読込み専用の場合、そのカーソル指定で導出される表は読込み専用となります。

    • 上記以外の場合、そのカーソル指定で導出される表は更新可能となります。

  • カーソル宣言の形式が、“表3.12 読込み専用カーソルとなる条件”のいずれかに該当する場合、読込み専用カーソルになります。いずれにも当てはまらない場合は、更新可能カーソルになります。

    表3.12 読込み専用カーソルとなる条件”のa)からt)は、問合せ指定で指定する要素です。また、u)は問合せ式で指定する要素です。v)からx)は、カーソル宣言で指定する要素です。w)とx)は、更新可能性句にFOR UPDATEを指定したときのみ更新可能カーソルとなります。

    表3.12 読込み専用カーソルとなる条件

    読込み専用カーソルとなるカーソル宣言の条件

    a) DISTINCTを指定している。

    DECLARE CSR CURSOR FOR
    SELECT DISTINCT COLA, COLB FROM SCM.TBL1

    b) 選択リストに演算式を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLC,COLA + COLB FROM SCM.TBL1

    c) 選択リストに集合関数を指定している。

    DECLARE CSR CURSOR FOR
    SELECT SUM(COLB) FROM SCM.TBL1

    d) 選択リストに同じ列を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLA,COLB,COLA,COLC
    FROM SCM.TBL1

    e) 選択リストに定数またはホスト変数を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLA,100 FROM SCM.TBL1

    f) 選択リストにデータ列関数を指定している。

    DECLARE CSR CURSOR FOR
    SELECT SUBSTRING(COL1 FROM 1 FOR 3)
    FROM SCM.TBL1

    g) 選択リストに数値関数を指定している。

    DECLARE CSR CURSOR FOR
    SELECT ABS(COL1) FROM SCM.TBL1

    h) 選択リストに日時値関数を指定している。

    DECLARE CSR CURSOR FOR
    SELECT TRUNC_DATE(COL1,'MONTH')
    FROM SCM.TBL1

    i) 選択リストにXMLQUERY関数を指定している

    DECLARE CSR CURSOR FOR
    SELECT XMLQUERY('/a[b/text() = 1]' PASSING COLX)
    FROM SCM.TBL1

    j) 選択リストにCASE式を指定している。

    DECLARE CSR CURSOR FOR
    SELECT CASE WHEN COL1=1 THEN 'ONE' END
    FROM SCM.TBL1

    k) 選択リストにCAST指定を指定している。

    DECLARE CSR CURSOR FOR
    SELECT CAST(COL1 AS CHAR(6))
    FROM SCM.TBL1

    l) 選択リストに連結演算子を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COL1 || COL2 FROM SCM.TBL1

    m) 選択リストにファンクションルーチンを指定している。

    DECLARE CSR CURSOR FOR
    SELECT USERFUNC1(C1,C2) FROM SCM.TBL1

    n) 選択リストに順序を指定している。

    DECLARE CSR CURSOR FOR
    SELECT SCM.順序1.NEXTVAL FROM SCM.TBL1

    o) 選択リストにROWNUMを指定している。

    DECLARE CSR CURSOR FOR
    SELECT ROWNUM, COLA FROM SCM.TBL1

    p) FROM句に2つ以上の表または結合表を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLA, COLZ FROM SCM.TBL1, SCM.TBL2

    q) FROM句に、ORDER BY句を指定した導出表を指定している。

    DECLARE CSR CURSOR FOR
    SELECT DCOLA
    FROM (SELECT COLA FROM SCM.TBL1 ORDER BY COLA)
    AS D1(DCOLA)

    r) FROM句にROWNUMを指定した導出表を指定している。

    DECLARE CSR CURSOR FOR
    SELECT DCOLA
    FROM (SELECT COLA FROM SCM.TBL1
    WHERE ROWNUM < 10) AS D1(DCOLA)

    s) GROUP BY句またはHAVING句を指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLA FROM SCM.TBL1 GROUP BY COLA

    t) WHERE句に副問合せを含んでいる。

    DECLARE CSR CURSOR FOR
    SELECT * FROM SCM.TBL1 WHERE COLA IN
    (SELECT COLZ FROM SCM.TBL2 WHERE COLY > 2000)

    u) UNIONを指定している。

    DECLARE CSR CURSOR FOR
    SELECT COLC FROM SCM.TBL1
    UNION SELECT COLX FROM SCM.TBL2

    v) 更新可能性句にFOR READ ONLYを指定している。

    DECLARE CSR CURSOR FOR SELECT COLA, COLB
    FROM SCM.TBL1 FOR READ ONLY

    w) ORDER BY句を指定し、更新可能性句を指定していない。

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

    x) SCROLLを指定し、更新可能性句を指定していない。

    DECLARE CSR SCROLL CURSOR FOR
    SELECT COLA, COLB FROM SCM.TBL1


ORDER BY
  • ORDER BY句を指定すると、カーソルの行の順序は、ORDER BY句のソート指定の順番になります。

  • ORDER BY句を省略すると、カーソルの行の順序に規則性はありません。

  • ORDER BY句が指定された場合、ソート指定の指定方法は次のとおりです。

    • ソート指定には値式を指定します。値式に指定可能な項目を以下に示します。

      表3.13 ソート指定の値式に指定可能な項目

      項目

      指定可否

      列指定

      符号なし整数

      値指定

        

        

      変数指定

      ×

      定数

      ×

      USER

      ×

      動的パラメタ指定

      ×

      項目参照

        

        

      パラメタ名

      ×

      SQL変数名

      ×

      集合関数指定

        

        

      COUNT(*)

      DISTINCT集合関数

      ALL集合関数

      数値式

      数値関数

      データ列値式

      データ列値関数

      日時値式

      日時値関数

      ○ (注)

      ファンクションルーチン指定

      時間隔値式

      CASE式

      CAST指定

      ROW_ID

      ×

      順序

      ×

      XMLQUERY関数

      ×

      ROWNUM

      ×

      ○: 指定可 ×: 指定不可

      注) CURRENT_DATE値関数、CURRENT_TIME値関数およびCURRENT_TIMESTAMP値関数は除く。

    • ソート指定に符号なし整数を指定すると、選択リストの左からの順番に対応する値式を指定したのと同じ意味です。

    • ソート指定に指定した値式が符号なし整数でない場合、列指定を含むことが必要です。

    • ソート指定に指定した値式が選択リストに指定されていない場合、問合せ指定にDISTINCTが指定されていてはなりません。

    • ソート指定に指定した値式が選択リストに指定されていない場合でグループ表の場合、グループ化列、GROUP BY句のAS句の列名、グループ化列またはGROUP BY句のAS句の列名を含む値式、グループ化関数あるいは集合関数指定であることが必要です。

    • 導出表にORDER BY句を指定する場合、ソート指定には、選択リストに指定していない値式を指定することはできません。

    • 導出表にORDER BY句を指定する場合、ソート指定には、列指定または符号なし整数を指定しなければなりません。

    • カーソル指定がUNIONを含み、ソート指定を符号なし整数以外で指定する場合は、一番左側の問合せ指定の選択リストが対象となります。この場合、選択リストに指定していない値式を指定することはできません。

    • ソート指定に同じ値式を複数指定することはできません。

    • ソート指定に指定した値式が選択リストに複数指定されていてはなりません。

  • ORDER BY句が指定された場合の扱いは次のとおりです。

    • ASCが指定された場合の行の順序は昇順となります。DESCが指定された場合は、降順となります。ASCもDESCも指定されない場合は、ASCが指定されたとみなされます。

    • ソートの昇順および降順の順序づけは、“2.12.1 比較述語”の比較の方法に従います。ただし、NULL値は、最大の値として処理します。そのため、昇順では末尾に、降順では先頭に扱われます。

    • ソートの優先順位は、指定された順になります。

    • ソート対象となる列データが同値である行の順序に規則性はありません。

  • ORDER BY句にBLOB型の値を指定することはできません。

  • ORDER BY句に順序は指定できません。また選択リストに指定した順序を符号なし整数で指定することもできません。

  • ORDER BY句にROWNUMは指定できません。

  • 問合せ指定の選択リストに“*”を指定した場合、ソート指定には列指定または符号なし整数でなければなりません。

FOR READ ONLYおよびFOR UPDATE(更新可能性句)
  • FOR READ ONLYおよびFOR UPDATEは、“更新可能性句”と呼びます。

  • 更新可能性句にFOR READ ONLYが指定された場合、そのカーソルは読込み専用カーソルとなります。

  • 更新可能性句にFOR UPDATEが指定された場合、そのカーソルは更新可能カーソルとなります。

  • 更新可能性句が省略された場合の扱いは次のとおりです。

    • ORDER BY句を指定している、SCROLLを指定している、または問合せ式が読込み専用となる場合は、そのカーソルは読込み専用カーソルとなります。

    • 上記以外の場合、そのカーソルは更新可能カーソルとなります。

  • カーソルの問合せ式が読込み専用の場合、FOR UPDATEは指定できません。

  • カーソルの問合せ式が更新可能である場合、ORDER BY句を指定する、またはSCROLLを指定するカーソルは、更新可能性句にFOR UPDATEを指定したときのみ更新可能カーソルとなります。

  • 更新可能性句にFOR READ ONLYを指定し、SET TRANSACTION文にREAD COMMITTEDが指定された場合、トランザクションを超越するカーソルとなります。ただし、トランザクションを超越するカーソルとして、32K以上のBLOB型は指定できません。

PARALLEL
  • PARALLELは、“並列指定”と呼びます。

  • 並列指定を指定した場合、表を並列に検索します。

実行オプション指定
  • 実行オプション指定は、占有モード、カーソルモードまたは最大件数を指定します。

占有モード指定
  • 占有モード指定は、問合せ指定を指定した場合に、問合せ指定のデータベース資源の占有の方法を指定します。

  • 占有モードを指定したSQL文が読み込んだデータベース資源は、占有モード指定により、以下のようにデータベース資源を占有します。なお、更新する行は占有モード指定にかかわらず、非共有モードでトランザクションの終了までデータベース資源を占有します。

    占有モード指定

    占有の方法

    EXCLUSIVE LOCK

    非共有モードでトランザクション終了までデータベース資源を占有します。

    SHARE LOCK

    共有モードでトランザクション終了までデータベース資源を占有します。

    FREE LOCK

    共有モードでSQL文終了までデータベース資源を占有します。ただし、DSO定義でPRECEDENCE(1)が指定されたSEQUENTIAL構造の表にアクセスする場合には、データベース資源を占有しません。

    NO LOCK

    データベース資源を占有しません。

  • 占有モードを指定したSQL文によって読み込まれた資源は、SET TRANSACTION文で指定された内容にかかわらず、以下のようになります。

    占有モード指定

    読込み水準

    EXCLUSIVE LOCK

    他のトランザクションによって占有されていない行を読み込みます。当該SQL文で読み込んだ行は、トランザクション終了まで他のトランザクションに更新されることはないため、一度読み込んだ行は他のトランザクションによって更新されないことが保証されます。

    SHARE LOCK

    他のトランザクションによって占有されていないか、または共有モードで資源を占有されている行を読み込みます。当該SQL文で読み込んだ行は、トランザクション終了まで他のトランザクションに更新されることはないため、一度読み込んだ行は他のトランザクションによって更新されないことが保証されます。

    FREE LOCK

    他のトランザクションによって占有されていないか、または共有モードで資源を占有されている行を読み込みます。ただし、DSO定義でPRECEDENCE(1)が指定されたSEQUENTIAL構造の表にアクセスする場合には、他のトランザクションでの占有の有無に関わらず、SQL文実行時にコミット済みの行のデータを読み込みます。いずれの場合も、当該SQL文で読み込んだ行は、他のトランザクションに更新されることがあるため、同一トランザクションで再検索すると最新の結果を検索することができます。

    NO LOCK

    他のトランザクションでどのような占有をされた資源でも参照することが可能なため、同一トランザクションで再検索すると最新の結果を検索することができます。

  • 占有モードの単位は、R_LOCKがYESの場合は行単位となります。R_LOCKがNOの場合は、ページ単位またはDSI単位の占有になります。

  • 動作環境パラメタにDSO_LOCKを指定したり、環境変数でRDBDSOを指定した場合、占有モードを指定したSQL文は実行できません。

カーソルモード指定
  • カーソルモードを指定することにより、占有モードを指定したカーソルをトランザクションを越えて保持することができます。カーソルモードを指定したカーソルは、トランザクションをコミットしてもトランザクションを越えてオープン状態を保持することができます。ただし、ROLLBACK文でトランザクションを終了させた場合や、トランザクションを取り消すようなエラーが発生した場合は、カーソルは自動的にクローズされます。

  • カーソルモード指定は、占有モード指定でFREE LOCKまたはNO LOCKの場合に指定できます。

  • 更新可能性句にFOR UPDATEを指定できません。

  • 32K以上のBLOB型の列を指定できません。

最大件数指定
  • 最大件数指定は、検索結果として取り出す件数を限定します。最大件数指定を指定すると、それ以上の行は返されません。

  • 最大件数指定に指定された値が0以下の場合、検索結果として取り出す件数は0件となります。

  • 最大件数指定に指定された値がNULLの場合、検索結果として取り出す件数は限定されず、すべての行が返されます。

  • ORDER BY句が指定されている場合、ソート指定に指定された順序に並び替えられた後、その先頭から、最大件数指定で指定された件数までが結果として取り出されます。ORDER BY句を指定しない場合は任意の順序で取り出されます。

  • 値指定にUSERは指定できません。

  • 指定値に指定できる値は、-2147483648から2147483647までの整数値です。

  • 値指定に変数指定または項目参照を指定した場合、データ型はINTEGER型またはSMALLINT型が指定可能です。

  • 値指定に動的パラメタ指定が指定された場合のDESCRIBE情報は、INTEGER型になります。

使用例

例1

カーソル宣言にORDER BY句を指定した例を示します。

DECLARE CSR1 CURSOR FOR
        SELECT COL1,COL2,COL3 FROM T1 WHERE COL4 > 10
        ORDER BY COL2 DESC,COL3 ASC


例2

スキーマ“S1”の表“T2”を検索します。読込みの水準として、他のトランザクションが更新中のデータを読むことができます。また、他のトランザクションの更新を止めず、排他を獲得せずに読み込むことができます。

DECLARE CUR1 CURSOR FOR
        SELECT C1,C2 FROM S1.T2
        WITH OPTION LOCK_MODE(NO LOCK)

例3

占有モード指定のカーソルを、トランザクションを越えて保持します。

スキーマ“S1”の表“T3”を検索します。検索を行うカーソルをオープンしたまま、トランザクションをコミットしてもカーソルは閉じないようにします。

EXEC SQL DECLARE CUR1 CURSOR FOR
    SELECT C1,C2  FROM S1.T3  WHERE C3 > DATE'2007-04-01'
    WITH OPTION LOCK_MODE(FREE LOCK) , CURSOR_MODE(HOLD);
      ~
EXEC SQL OPEN CUR1;
EXEC SQL FETCH CUR1 INTO :OUTVAL1, :OUTVAL2;
      ~
EXEC SQL COMMIT WORK;  →COMMIT文を実行してもカーソルはクローズされません。
      ~
EXEC SQL FETCH CUR1 INTO :OUTVAL1, :OUTVAL2;
      ~  →データの終了
EXEC SQL CLOSE CUR1;