トップページへ PASSJ ブログへ
トップページへ
分科会
特集!
コミュニケーション
資格
セミナー・コンファレンス
インフォメーション
Oracleキーワードから学ぶ、逆引き! SQL Server入門
文=株式会社CSK 教育サービス事業部
第6回
プログラミング編 スペシャルキーワード
カーソル
Oracle ServerとSQL Serverのカーソルの機能で大きく違う点は、SQL Serverではオープン時にカーソル引数が使えないこと、そしてフェッチの方向が自由に設定できることです。SQL Serverの場合は、順方向フェッチ、逆方向フェッチなど、さまざまなフェッチの方法があります。

Oracle Serverのカーソル概要


Oracle ServerのPL/SQLブロック内で表にアクセスするためには、必ずカーソルを使用します。Oracle Serverで提供するカーソルには、暗黙カーソルと明示カーソルの2種類があります。前者はカーソル定義を行うことなく利用できるもので、後者はカーソル定義を行った上で使用します。この2つのカーソルは、次のように使い分けます。

●暗黙カーソル……1行の結果を戻すSELECT文およびDML文
●明示カーソル……1行以上の結果を戻すSELECT文

データを1行だけ取り出し、PL/SQLブロック内で使用するのであれば宣言の必要ない暗黙カーソルがコードを書く上で負担が少なくなります。ただし複数行の結果を戻すSELECT文の場合は、必ず明示カーソルを使用します。暗黙カーソル使用時に複数行の結果が戻るとエラーが発生します。



SQL Serverのカーソル概要


一方、SQL Serverでは、表にアクセスする場合に、カーソルを使用する方法と使用しない方法があります。この2つの方法について以下に紹介します。

●カーソル未使用

カーソルを使用しないSELECT文は、「既定の結果セット」と呼ばれ、プログラムの呼び出し元に直接結果を戻します。このカーソルを使用しない方法は、Transact-SQLのプログラム内で複数行の結果を1行ずつ操作する時には使用しません。SELECT文の中で、取得した結果を変数に格納してその値をプログラム内で使用したり、ストアドプロシージャなどのプログラムの中からクライアントに結果セットを返したりする場合に使用します。

●カーソル使用

Oracle Serverの明示カーソルに該当するカーソルです。ブロック内で宣言し、SELECTした結果をプログラム内で1行ずつ操作することができます。

Transact-SQLブロック内でカーソルを利用する場合の手順は次のようになります。

1.カーソルの宣言
2.カーソルのオープン
3.カーソルのフェッチ
4.フェッチ行の操作
5.カーソルのクローズ
6.カーソル定義の開放

カーソルを利用する手順についてOracle Serverとの違いはさほどありません。しかし、各ステップで使用する構文などに違いがあります。では、次に各ステップで使用する構文について詳細に見ていきましょう。



SQL Serverのカーソル構文


1.カーソルの宣言

カーソルの宣言には、DECLARE CURSORステートメントを使用します。

DECLARE カーソル名 CURSOR
(1)[FORWARD_ONLY | SCROLL]
(2)[READ_ONLY]FOR select文
(3)[FOR UPDATE [OF 列名,…]] 

(1) フェッチ方向の指定
SQL Serverでは、結果セット上の次の行へフェッチする「順方向フェッチ」以外に、前の行へフェッチする「逆方向フェッチ」などをサポートしています。
・FORWARD_ONLY……順方向フェッチのみ
・SCROLL……順方向および逆方向フェッチも可能

(2) フェッチ行の更新
フェッチした行に対する変更および削除の可および不可を指定します。既定では更新可能になっています。
・ READ_ONLY……読込み専用カーソル

(3) 更新可能列の指定
    カーソル内の列を更新可能とするか否かを指定します。このオプションを指定しない場合は、すべての列が更新可能となります。


2.カーソルのオープン


カーソルを利用するためにはオープン操作を行います。Oracle Serverでは、オープン時にパラメータを渡すことができましたが、SQL Serverでは渡すことはできません。

OPEN カーソル名


3.カーソルのフェッチ

カーソルを通して結果セットからデータを取り出すためにフェッチを行います。このフェッチのときに、順方向や逆方向という動きを指定します。SQL ServerカーソルとOracle Severカーソルの一番の違いが、このフェッチ方向を指定できるというところです。Oracle Severは順方向フェッチのみです。

FETCH
[NEXT | PRIOR |FIRST |LAST]
FROM カーソル名
INTO 変数名,…

・NEXT…… 順方向フェッチで、結果セット上のカーソルが指しているデータの次のデータを取り出します。
・PRIOR…… 逆方向フェッチで、結果セット上のカーソルが指しているデータの直前のデータを取り出します。
・FIRST…… 結果セットの先頭データを取り出します。
・LAST…… 結果セットの最終データを取り出します。


フェッチ後にデータが取り出されたのか、取り出されてないのか、または結果セットの最後まで達したのかを調べる方法として、@@FETCH_STATUS関数を使用します。

説明 Oracle Serverの場合
0 フェッチ成功 カーソル名%FOUND
-1 結果セットの範囲外に達した カーソル名%NOTFOUND
-2 要求した行がカーソルのオープン後に削除された場合 該当なし


4.フェッチ行の操作

CURRENT OF句を使い、フェッチしたデータのDELETEおよびUPDATEが可能です。Oracle ServerとSQL Serverにおける違いはありません。

UPDATE操作 DELETE操作
UPDATE 表名
SET
WHERE CURRENT OF カーソル名
DELETE FROM 表名
WHERE CURRENT OF カーソル名


5.カーソルのクローズおよびカーソル定義の削除

カーソルの利用が終了した場合、カーソルをクローズします。SQL Serverカーソルでは、カーソルのクローズを行ってもカーソル定義はセッション終了まで残ります。よって再びカーソル定義を行うことなくオープンすることができます。一方、Oracle Serverカーソルは、クローズを行うことで同時に定義も削除されます。

・カーソルのクローズ

CLOSE カーソル名

・カーソル定義の削除

DEALLOCATE カーソル名



カーソル定義例


最後に、employees表からfirst_name列とlast_name列を取り出し、画面に表示するブロックを、Oracle ServerとSQL Serverそれぞれ示します。

●Oracle Server

DECLARE
vfname VARCHAR2(10);
vlname VARCHAR2(10);
CURSOR emp_cur IS
SELECT first_name,last_name FROM employees;
BEGIN
OPEN emp_cur;
FETCH emp_cur INTO vfname,vlname;
WHILE emp_cur%FOUND LOOP     
DBMS_OUTPUT.PUT_LINE(vfname|| '-' || vlname);
FETCH emp_cur INTO vfname,vlname;
END LOOP;
CLOSE emp_cur;
END;

●SQL Server

DECLARE
@vfname VARCHAR(10), 
@vlname VARCHAR(10)
DECLARE emp_cur CURSOR FOR
SELECT first_name,last_name FROM employees
OPEN emp_cur
FETCH NEXT FROM emp_cur INTO @vfname,@vlname
WHILE (@@FETCH_STATUS=0)
BEGIN
SELECT @vfname + '-' + @vlname
FETCH NEXT FROM emp_cur INTO @vfname,@vlname
END
CLOSE emp_cur
DEALLOCATE emp_cur



・ 第1回 基本用語編:データベースオブジェクト
・ 第2回 ユーティリティ編:SQL*Plus
・ 第3回 アーキテクチャ編(1):インスタンスとデータベース
・ 第4回 アーキテクチャ編(2):セグメント/エクステント/データブロック
・ 第5回 アーキテクチャ編(3):索引
・ 第6回 プログラミング編:カーソル
・ 第7回 トランザクション/ロック編:読み取り一貫性
・ 第8回 バックアップとリカバリ編:スタンバイ・データベース
・ 第9回 ユーザー管理編:ロール
・ 第10回 パフォーマンスチューニング編:EXPLAIN PLAN(実行プランの表示)


著者プロフィール
株式会社CSK 教育サービス事業部
http://www.cskedu.com/
OracleとSQL Server、それぞれのトレーニングコースを担当するトレーナー3名体制で執筆しています。メンバーは、金子真由美、浦山裕恭、浅見淳子。
今回の執筆担当
浦山裕恭(URAYAMA, Hiroyasu)
会計システムの導入コンサルティングを経て、1997年からOracleデータベースのインストラクターを担当しています。現在では、Oracleデータベース以外にOracle E-Business Suite関連やSQL Server関連のコースも担当しています。ちなみに、九州男児ですがお酒は弱いです。

← 特集!DBバイリンガル 目次

PASSJメールニュース 著作権ついて プライバシーポリシー リンクポリシー お問い合わせ
(C) 2005 Professional Association for SQL Server Japan. All rights reserved.