次の方法で共有


カーソルの種類について

JDBC ドライバーのダウンロード

リレーショナル データベースで操作を実行する場合、行の完全なセットが操作の対象になります。 SELECT ステートメントでは、WHERE 句で指定した条件を満たすすべての行のセットが返されます。 このステートメントが返す行の完全なセットを結果セットと呼びます。 アプリケーションでは、必ずしも、結果セット全体をひとまとめに使用して作業することが効率的であるとは限りません。 そのため、このようなアプリケーションでは、一度に 1 行、または少数行から成るブロックを使用する方法が必要になります。 カーソルはそのメカニズムを提供する結果セットの拡張機能です。

カーソルは、次の項目を実行することで、結果セットの処理を拡張します。

  • 結果セット内の特定の行に位置付けることができます。
  • 結果セット内の現在位置から 1 行または 1 ブロックの行を取得します。
  • 結果セット内の現在位置の行データを修正できます。
  • 結果セット内に示されている、データベース データに対して他のユーザーが行った変更をさまざまなレベルで表示できます。

注意

SQL Server のカーソルの種類の詳細については、「カーソルの種類」を参照してください。

JDBC の仕様では、他のジョブによって行われた変更を認識する、または認識しない順方向専用およびスクロール可能なカーソルや、読み取り専用または更新可能なカーソルがサポートされています。 この機能は、SQL Server 用 Microsoft JDBC ドライバー の SQLServerResultSet クラスによって提供されます。

解説

JDBC ドライバーでは、指定された動作オプションと共に、次の結果セットとカーソルの種類がサポートされています。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) 該当なし 順方向専用、読み取り専用 直接 フル

アプリケーションで結果セットに対して 1 回の (順方向の) パススルーを行う必要があります。 このパスは既定の動作です。TYPE_SS_DIRECT_FORWARD_ONLY カーソルと同じように動作します。 ステートメントの実行時には、サーバーからメモリに結果セット全体が読み込まれます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) 該当なし 順方向専用、読み取り専用 直接 adaptive

アプリケーションで結果セットに対して 1 回の (順方向の) パススルーを行う必要があります。 TYPE_SS_DIRECT_FORWARD_ONLY カーソルと同じように動作します。 ドライバーによって、アプリケーションからの要求に応じて行がサーバーから読み取られ、クライアント側のメモリの使用が最小限に抑えられます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_FORWARD_ONLY (CONCUR_READ_ONLY) 高速順方向 順方向専用、読み取り専用 カーソル (cursor) 該当なし

アプリケーションでサーバー カーソルを使用して結果セットに対する 1 回の (順方向の) パススルーを行う必要があります。 TYPE_SS_SERVER_CURSOR_FORWARD_ONLY カーソルと同じように動作します。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_FORWARD_ONLY (CONCUR_UPDATABLE) 動的 (順方向専用) 順方向専用、更新可能 該当なし 該当なし

アプリケーションで 1 行以上の行を更新するには、結果セットに対して 1 回の (順方向の) パススルーを行う必要があります。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

既定では、アプリケーションで SQLServerResultSet オブジェクトの setFetchSize メソッドが呼び出されるとフェッチ サイズが固定されます。

Note

JDBC ドライバーには、ステートメントの実行結果を SQL Server から (一度に取得するのではなく) 必要に応じて取得できるアダプティブ バッファリングの機能が備わっています。 たとえば、アプリケーションからメモリに収まりきらないほどの大きなデータを取得する必要があっても、アダプティブ バッファリングが作用することで、クライアント アプリケーションがそのような値をストリームとして取得できるようになります。 ドライバーの既定の動作は "adaptive" です。 ただし、順方向専用の更新可能な結果セットに対するアダプティブ バッファリングを使用するには、アプリケーションは、SQLServerStatement オブジェクトの setResponseBuffering メソッドに、String 値 "adaptive" を指定して、このメソッドを明示的に呼び出す必要があります。 コード例については、「大きなデータを更新するサンプル」を参照してください。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SCROLL_INSENSITIVE 静的 スクロール可能、更新不可。

外部の行の更新、挿入、および削除は参照できません。
なし 該当なし

アプリケーションで、データベース スナップショットが必要になります。 結果セットは更新できません。 CONCUR_READ_ONLY のみがサポートされます。 それ以外のコンカレンシータイプは、このカーソル タイプと組み合わせて使用すると例外が発生します。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SCROLL_SENSITIVE (CONCUR_READ_ONLY) Keyset スクロール可能、読み取り専用。 外部の行の更新を参照できます。削除はデータの欠落によって表されます。

外部の行の挿入は参照できません。
なし 該当なし

アプリケーションで、既存の行についてのみ、変更されたデータを調べる必要があります。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SCROLL_SENSITIVE (CONCUR_UPDATABLE、CONCUR_SS_SCROLL_LOCKS、CONCUR_SS_OPTIMISTIC_CC、CONCUR_SS_OPTIMISTIC_CCVAL) Keyset スクロール可能、更新可能。

外部および内部の行の更新を参照できます。削除はデータの欠落によって表されます。挿入は参照できません。
なし 該当なし

アプリケーションから ResultSet オブジェクトを使用して既存の行のデータを変更できます。 また、ResultSet オブジェクト以外から、他のアプリケーションによって行われた行に対する変更も参照できます。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_DIRECT_FORWARD_ONLY 該当なし 順方向専用、読み取り専用 該当なし full または adaptive

整数値 2003 です。 全体がバッファーされた、読み取り専用のクライアント側カーソルを使用できます。 サーバー カーソルは作成されません。

コンカレンシーの種類としては CONCUR_READ_ONLY のみがサポートされます。 それ以外の同時実行タイプは、このカーソル タイプと組み合わせて使用すると例外が発生します。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SERVER_CURSOR_FORWARD_ONLY 高速順方向 順方向専用 該当なし 該当なし

整数値 2004 です。 サーバー カーソルを使用して、すべてのデータに高速にアクセスできます。 使用するコンカレンシーの種類が CONCUR_UPDATABLE である場合に更新できます。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

この場合にアダプティブ バッファリングを使用するには、アプリケーションで明示的に String 値 "adaptive" を指定して SQLServerStatement オブジェクトの setResponseBuffering メソッドを呼び出す必要があります。 コード例については、「大きなデータを更新するサンプル」を参照してください。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SCROLL_STATIC 静的 他のユーザーによる更新は反映されません。 なし 該当なし

整数値 1004 です。 アプリケーションで、データベース スナップショットが必要になります。 このオプションは JDBC TYPE_SCROLL_INSENSITIVE に対する SQL Server 固有のシノニムです。コンカレンシー設定の動作は同じです。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SCROLL_KEYSET (CONCUR_READ_ONLY) Keyset スクロール可能、読み取り専用。 外部の行の更新を参照できます。削除はデータの欠落によって表されます。

外部の行の挿入は参照できません。
なし 該当なし

整数値 1005 です。 アプリケーションで、既存の行についてのみ、変更されたデータを調べる必要があります。 このオプションは JDBC TYPE_SCROLL_SENSITIVE に対する SQL Server 固有のシノニムです。コンカレンシー設定の動作は同じです。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SCROLL_KEYSET (CONCUR_UPDATABLE、CONCUR_SS_SCROLL_LOCKS、CONCUR_SS_OPTIMISTIC_CC、CONCUR_SS_OPTIMISTIC_CCVAL) Keyset スクロール可能、更新可能。

外部および内部の行の更新を参照できます。削除はデータの欠落によって表されます。挿入は参照できません。
なし 該当なし

整数値 1005 です。 アプリケーションは、既存の行について変更済みデータを参照したり、データを変更したりする必要があります。 このオプションは JDBC TYPE_SCROLL_SENSITIVE に対する SQL Server 固有のシノニムです。コンカレンシー設定の動作は同じです。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SCROLL_DYNAMIC (CONCUR_READ_ONLY) 動的 スクロール可能、読み取り専用。

外部の行の更新と挿入を参照できます。削除は現在のフェッチ バッファー内の一時的なデータ欠落として表されます。
該当なし 該当なし

整数値 1006 です。 アプリケーションで、既存の行について、変更されたデータを調べる必要があります。また、カーソルの有効期間内に挿入および削除された行を調べる必要があります。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

結果セット (カーソル) の種類 SQL Server のカーソルの種類 特性 選択方法 応答バッファリング
TYPE_SS_SCROLL_DYNAMIC (CONCUR_UPDATABLE、CONCUR_SS_SCROLL_LOCKS、CONCUR_SS_OPTIMISTIC_CC、CONCUR_SS_OPTIMISTIC_CCVAL) 動的 スクロール可能、更新可能。

外部および内部の行の更新と挿入を参照できます。削除は現在のフェッチ バッファー内の一時的なデータ欠落として表されます。
該当なし 該当なし

整数値 1006 です。 アプリケーションから ResultSet オブジェクトを使用して、既存の行のデータを変更したり、行の挿入または削除を行ったりすることができます。 また、ResultSet オブジェクト以外から、他のアプリケーションによって行われた行に対する変更、挿入、および削除も参照できます。

行は、フェッチ サイズで指定されたブロック単位でサーバーから取得されます。

カーソルの行の指定

TYPE_FORWARD_ONLY、TYPE_SS_DIRECT_FORWARD_ONLY、および TYPE_SS_SERVER_CURSOR_FORWARD_ONLY カーソルは、行を指定するメソッドとしては next メソッドだけをサポートしています。

TYPE_SS_SCROLL_DYNAMIC カーソルでは、absolute および getRow メソッドはサポートされていません。 absolute メソッドについては、動的カーソルに対して first メソッドおよび relative メソッドを組み合わせて呼び出すことで、同等の結果を得ることができます。

getRow メソッドは、TYPE_FORWARD_ONLY、TYPE_SS_DIRECT_FORWARD_ONLY、TYPE_SS_SERVER_CURSOR_FORWARD_ONLY、TYPE_SS_SCROLL_KEYSET、および TYPE_SS_SCROLL_STATIC カーソルのみでサポートされています。 getRow メソッドは、どの順方向専用カーソルについても、そのカーソルを使用してそれまでに読み取られた行数が返されます。

注意

アプリケーションでサポートされていない、カーソルの行を指定する呼び出しを行った場合、または getRow メソッドに対してサポートされていない呼び出しを行った場合は、"要求された操作は、このカーソルの種類ではサポートされていません" という意味のメッセージで例外がスローされます。

削除された行を参照できるのは、TYPE_SS_SCROLL_KEYSET および等価である TYPE_SCROLL_SENSITIVE カーソルの場合のみです。 削除された行にカーソルが置かれている場合、列の値を得ることはできず、rowDeleted メソッドによって "true" が返されます。 get<Type> メソッドを呼び出すと、"削除された行から値は取得できません" というメッセージで例外がスローされます。 削除された行を更新することはできません。 削除された行に対して update<Type> メソッドの呼び出しを試みると、"削除された行を更新することはできません" というメッセージで例外がスローされます。 TYPE_SS_SCROLL_DYNAMIC カーソルも、現在のフェッチ バッファーからカーソルが移動するまでは同じ動作です。

順方向カーソルと動的カーソルでは、フェッチ バッファー内でカーソルにアクセスできる間だけ、削除された行を同様の方法で参照することができます。 順方向カーソルの場合、この動作は非常に単純です。 動的カーソルの場合は、フェッチ サイズが 1 より大きい場合に複雑になります。 アプリケーションでは、フェッチ バッファーによって定義された範囲内でカーソルを前後に移動できますが、更新が行われた元のフェッチ バッファーが移動した場合には、削除された行が参照できなくなります。 アプリケーションで、一時的に削除された行を動的カーソルを使用して参照しない場合は、FETCH RELATIVE (0) を使用する必要があります。

TYPE_SS_SCROLL_KEYSET または TYPE_SCROLL_SENSITIVE カーソル行のキー値がカーソルによって更新されると、更新された行がカーソルの選択基準を満たすかどうかにかかわらず、結果セット内でその行の元の位置が維持されます。 行がカーソルの外部で更新されると、削除された行がその行の元の位置に現れます。ただし、その行がカーソル内に現れるのは、新しいキー値を持ちカーソル内にもともと存在していた別の行が、その時点で削除されている場合だけです。

動的カーソルの場合は、更新された行は、フェッチ バッファーで定義された範囲が移動するまでは、フェッチ バッファー内での位置が維持されます。 更新された行はその後結果セット内の異なる場所に再度現れるか、または完全に削除されます。 結果セット内での一時的な不整合を回避する必要のあるアプリケーションでは、フェッチ サイズを 1 にする必要があります (既定では、CONCUR_SS_SCROLL_LOCKS のコンカレンシーの場合は 8 行、その他のコンカレンシーの場合は 128 行です)。

カーソルの変換

SQL Server では、要求されたものと異なる種類のカーソルを実装することもできます。これは暗黙のカーソル変換 (またはカーソルの下位変換) と呼ばれます。

SQL Server 2000 (8.x) では、ResultSet.TYPE_SCROLL_SENSITIVE および ResultSet.CONCUR_UPDATABLE の結果セットを使用してデータを更新すると、"カーソルは読み取り専用です" というメッセージで例外がスローされます。 この例外が発生するのは、SQL Server 2000 (8.x) によってその結果セットに対して暗黙のカーソル変換が行われ、要求した更新可能なカーソルが返されていないからです。

この問題を回避するには、次のいずれかの解決策を行ってください。

  • 基になるテーブルに主キーがあることを確認する。
  • ステートメントを作成する際に、ResultSet.TYPE_SCROLL_SENSITIVE の代わりに SQLServerResultSet.TYPE_SS_SCROLL_DYNAMIC を使用する。

カーソルの更新

直接の更新は、カーソルの種類およびコンカレンシーで更新が可能なカーソルについてサポートされています。 カーソルの位置が結果セット内の更新可能な行でない (get<Type> メソッドの呼び出しが成功しなかった) 場合、update<Type> メソッドの呼び出しで、"結果セットに現在の行がありません" というメッセージで例外がスローされます。JDBC の仕様には、CONCUR_READ_ONLY であるカーソルの列に対して更新メソッドが呼び出されると、例外が発生すると記載されています。 更新または削除の競合のようなオプティミスティック同時実行制御の競合があった場合など、行が更新可能でない場合は、insertRowupdateRow、または deleteRow が呼び出されるまで、例外は発生しません。

update<Type> の呼び出し後は、updateRow または cancelRowUpdates が呼び出されるまで、影響を受けた列に get<Type> でアクセスすることはできません。 この動作により、サーバーによって返された型とは異なる型を使用して列が更新されるという問題と、その後の getter 呼び出しでクライアント側の型変換が生じ不正確な結果になるという問題が回避されます。 get<Type> を呼び出すと、"更新された列には updateRow() または cancelRowUpdates() が呼び出されるまでアクセスできません" というメッセージで例外がスローされます。

Note

更新された列がない場合に updateRow メソッドが呼び出されると、JDBC ドライバーでは "updateRow() が呼び出されましたが、列が更新されていません" という意味のメッセージで例外がスローされます。

moveToInsertRow が呼び出された後に、get<Type>、update<Type>、insertRow、およびカーソルの行を指定するメソッド (moveToCurrentRow を含む) 以外のメソッドが結果セットに対して呼び出された場合は、例外がスローされます。 moveToInsertRow メソッドによって結果セットが挿入モードになり、カーソルの行を指定するメソッドによって挿入モードが終了します。 相対的なカーソル行を指定する呼び出しでは、moveToInsertRow が呼び出される前の位置を基準にカーソルが移動します。 カーソルの行を指定する呼び出しの後は、その結果得られたカーソルの位置が新しいカーソル位置になります。

挿入モードで実行されたカーソルの行を指定する呼び出しが失敗した場合、その呼び出し後のカーソル位置は、moveToInsetRow が呼び出される前の元のカーソル位置になります。 insertRow が失敗すると、カーソルは挿入行に残り、カーソルは挿入モードのままになります。

挿入行の列は、最初は初期化されていない状態です。 update<Type> メソッドを呼び出すことで、列の状態が初期化済みに設定されます。 初期化されていない列に対して get<Type> メソッドを呼び出すと、例外がスローされます。 insertRow メソッドを呼び出すと、挿入行のすべての列が初期化されていない状態に戻ります。

insertRow メソッドが呼び出されたときに初期化されていない列があった場合、その列の既定値が挿入されます。 既定値がなく、列で null が許容される場合は、null が挿入されます。 既定値がなく、列で null が許容されない場合は、サーバーからエラーが返され、例外がスローされます。

注意

getRow メソッドを挿入モードで呼び出すと、0 が返されます。

JDBC ドライバーでは、位置を指定した更新または削除はできません。 JDBC の仕様によると、setCursorName メソッドを使用しても効果はなく、getCursorName メソッドを呼び出すと例外がスローされます。

読み取り専用および静的カーソルは更新できません。

SQL Server では、サーバー カーソルの使用が 1 つの結果セットに制限されています。 バッチまたはストアド プロシージャに複数のステートメントが含まれる場合は、順方向専用かつ読み取り専用のクライアント カーソルを使用する必要があります。

関連項目

JDBC ドライバーによる結果セットの管理