CLI の手引きおよび解説書

SQLSetPos - 行セット (Rowset) でカーソル位置を設定する

目的


仕様: DB2 CLI 5.0 ODBC 1  

SQLSetPos() は、行セットでカーソル位置を設定します。

構文

SQLRETURN   SQLSetPos        (SQLHSTMT          StatementHandle,
                              SQLUSMALLINT      RowNumber,
                              SQLUSMALLINT      Operation,
                              SQLUSMALLINT      LockType);

関数引き数

表 166. SQLSetPos 引き数
データ・タイプ 引き数 使用法 説明
SQLHSTMT StatementHandle 入力 ステートメント・ハンドル。
SQLUSMALLINT RowNumber 入力

Operation 引き数の指定操作を実行する行セット内の行位置。 RowNumber が 0 だと、操作は行セットの各行に適用されます。

追加情報については、『RowNumber 引き数』を参照してください。

SQLUSMALLINT Operation 入力 以下を実行する操作です。
  • SQL_POSITION
  • SQL_REFRESH
  • SQL_UPDATE
  • SQL_DELETE
  • SQL_ADD

追加情報については、『Operation 引き数』を参照してください。

ODBC は以下の操作も指定しますが、これは後方互換性を保つために過ぎません。この操作は DB2 CLI でもサポートされています。

  • SQL_ADD

DB2 CLI は、SQLSetPos() 呼び出しで SQL_ADD をサポートしていますが、 Operation 引き数を SQL_ADD に設定して SQLBulkOperations() を使用するようお勧めします。詳しくは、SQLBulkOperations - 行のセットの追加、更新、削除、または取り出しを参照してください。

SQLUSMALLINT LockType 入力 Operation 引き数での指定操作を実行後、行のロック方法を指定します。
  • SQL_LOCK_NO_CHANGE
ODBC は以下の操作も指定しますが、DB2 CLI ではサポートされません。
  • SQL_LOCK_EXCLUSIVE
  • SQL_LOCK_UNLOCK
追加情報については、『LockType 引き数』を参照してください。

使用法

RowNumber 引き数

RowNumber 引き数は行セットの行数を指定し、それに対して Operation 引き数の指定操作を実行します。 RowNumber が 0 だと、操作は行セットの各行に適用されます。 RowNumber は、0 以上、行セット内の行数以下にする必要があります。

C 言語では、配列は 0 ベースで、RowNumber 引き数は 1 ベースです。たとえば、行セットの第 5 行を更新する場合、アプリケーションは行セット・バッファーを配列指数 4 で変更しますが、 RowNumber には 5 を指定します。

すべての操作で、カーソルは RowNumber によって指定される行に置かれます。以下の操作では、カーソル位置が必要になります。

アプリケーションは、SQLSetPos() の呼び出し時にカーソル位置を指定することができます。一般には、SQL_POSITION または SQL_REFRESH 操作で SQLSetPos() を呼び出してカーソル位置を決めてから、位置指定の更新または削除ステートメントを実行したり、 SQLGetData() を呼び出したりします。

Operation 引き数

データ・ソースがどのオプションをサポートしているのかを判別するために、アプリケーションは、カーソルのタイプに基づいて、以下のいずれかの情報タイプを使用して SQLGetInfo() を呼び出します。

SQL_POSITION

DB2 CLI は、RowNumber で指定された行にカーソルを置きます。

SQL_ATTR_ROW_OPERATION_PTR ステートメント属性が示す行状況配列の内容は、 SQL_POISTION Operation では無視されます。

SQL_REFRESH

DB2 CLI は、RowNumber で指定された行にカーソルを置き、その行の行セット・バッファーのデータをリフレッシュします。 DB2 CLI がどのように行セット・バッファーのデータを戻すかについて、詳しくは、 SQLFetchScroll() にある行ごとのバインドおよび列ごとのバインドの説明を参照してください。

SQL_REFRESH の Operation を指定した SQLSetPos() は、現行の取り出し行セット内の行の状況と内容だけを更新します。これにはブックマークのリフレッシュも含まれます。バッファー内のデータがリフレッシュされますが、再取り出しはされないため、行セットのメンバーシップは固定です。

SQLSetPos() でのリフレッシュが正常に実行されても、 SQL_ROW_DELETED の行状況は変更されません。行セット内の削除された行は、次の取り出しが行われるまでは削除されたものとしてマークされたままです。カーソルがパッキングをサポートしている場合、それらの行は次の取り出しで完全になくなります (この場合、削除された行は後続の SQLFetch() または SQLFetchScroll() では、戻されません)。

SQLSetPos() でのリフレッシュが正常に実行されると、 SQL_ROW_ADDED の行状況が SQL_ROW_SUCCESS に変更されます (行状況配列がある場合)。

SQLSetPos() でのリフレッシュにより、 SQL_ROW_UPDATED の行状況が行の新しい状況に変更されます (行状況配列がある場合)。

行での SQLSetPos() 操作でエラーが発生すると、行状況は SQL_ROW_ERROR に設定されます (行状況配列がある場合)。

SQL_CONCUR_ROWVER または SQL_CONCUR_VALUES の SQL_ATTR_CONCURRENCY ステートメント属性でオープンするカーソルの場合、 SQLSetPos() でのリフレッシュによって、データ・ソースが使用する楽観並行値を更新し、行の変更を検出します。これは、リフレッシュされる各行ごとに生じます。

SQL_REFRESH 操作 では、行状況配列の内容が無視されます。

SQL_UPDATE

DB2 CLI は、RowNumber で指定された行にカーソルを置き、行セット・バッファー内の値 (SQLBindCol() の中の TargetValuePtr 引き数) で、基礎となるデータ行を更新します。データの長さは、長さ / 標識バッファー (SQLBindCol() の中の StrLen_or_IndPtr 引き数) から検索されます。長さが SQL_COLUMN_IGNORE の列があれば、その列は更新されません。行の更新後、行状況配列の対応する要素が、 SQL_ROW_UPDATED または SQL_ROW_SUCCESS_WITH_INFO に更新されます (行状況配列がある場合)。

SQL_ATTR_ROW_OPERATION_PTR ステートメント属性が指し示す行操作配列を使用して、バルク更新中は現行行セットの行を無視するよう指示することができます。詳細については、『状況および操作配列』を参照してください。

SQL_DELETE

DB2 CLI は、RowNumber で指定された行にカーソルを置き、基礎となるデータ行を削除します。そして、行状況配列の対応する要素を SQL_ROW_DELETED に変更します。行が削除された後、以下のものはこの行に関して有効でなくなります。

削除された行は、静的およびキー・セットによって操作されるカーソルにとってはまだ可視です。しかし、(SQL_ATTR_ROW_STATUS_PTR ステートメント属性が指す) 実装行状況配列の中の削除された行の項目は、 SQL_ROW_DELETED に変更されます。

SQL_ATTR_ROW_OPERATION_PTR ステートメント属性が指し示す行操作配列を使用して、バルク削除中は現行行セットの行を無視するよう指示することができます。詳細については、『状況および操作配列』を参照してください。

SQL_ADD

ODBC は SQL_ADD Operation も指定しますが、これは後方互換性を保つために過ぎません。この操作は DB2 CLI でもサポートされています。しかし、Operation 引き数を SQL_ADD に設定して、 SQLBulkOperations() を使用するようお勧めします。

詳しくは、SQLBulkOperations - 行のセットの追加、更新、削除、または取り出しを参照してください。

LockType 引き数

LockType 引き数により、アプリケーションは並行性を制御することができます。一般に、並行性レベルおよびトランザクションをサポートするデータ・ソースは、 LockType 引き数の SQL_LOCK_NO_CHANGE 値だけをサポートします。

LockType 引き数は、単一のステートメントで指定しますが、ロックは、同じ特権をその接続でのすべてのステートメントに与えます。特に、あるステートメントが接続で得たロックは、同じ接続の別のステートメントによってロック解除可能です。

ODBC は、以下の LockType 引き数を定義します。 DB2 CLI は SQL_LOCK_NO_CHANGE をサポートします。データ・ソースがサポートしているロックを判別するために、アプリケーションは、 SQL_LOCK_TYPES 情報タイプの指定された SQLGetInfo() を呼び出します。


表 167. 操作値
LockType 引き数 ロック・タイプ
SQL_LOCK_NO_CHANGE 行が、 SQLSetPos() の呼び出し前と同じロック状態またはロック解除状態にあるかどうかを確認します。 LockType のこの値によって、明示的行レベル・ロックをサポートしていないデータ・ソースでも、現行の並行性およびトランザクション分離レベルが何らかのロックを必要とする場合に、それを使用できるようになります。
SQL_LOCK_EXCLUSIVE DB2 CLI ではサポートされない。行を排他的にロックする。
SQL_LOCK_UNLOCK DB2 CLI ではサポートされない。行をロック解除する。

状況および操作配列

以下の状況および操作配列は、 SQLSetPos() の呼び出し時に使用します。

状況および操作配列の要素数は、行セットの行数に等しくなければなりません。 (SQL_ATTR_ROW_ARRAY_SIZE ステートメント属性で定義されます。)

行状況配列については、SQLFetch - 次の行の取り出しを参照してください。

戻りコード

診断

表 168. SQLSetPos SQLSTATE
SQLSTATE 説明 解説
01000 警告。 通知メッセージ。 (関数は、SQL_SUCCESS_WITH_INFO を戻します。)
01004 データが切り捨てられました。 Operation 引き数は SQL_REFRESH で、データ・タイプ SQL_C_CHAR または SQL_C_BINARY の 1 つまたは複数の列用に戻されるストリングや 2 進データは、非ブランク文字または非ヌル文字の 2 進データの短縮形となります。
01S01 行の中にエラーがあります。 RowNumber 引き数は 0 で、 Operation 引き数で指定した操作の実行中に、 1 つまたは複数の行でエラーが発生しました。

(複数行操作の全体ではなく 1 つまたはそれ以上の行でエラーが発生すると、 SQL_SUCCESS_WITH_INFO が戻され、また、単一行操作でエラーが発生すると、 SQL_ERROR が戻されます。)

01S07 小数が切り捨てられました。 Operation 引き数は SQL_REFRESH で、アプリケーション・バッファーのデータ・タイプは SQL_C_CHAR や SQL_C_BINARY ではなく、 1 つまたは複数の列用にアプリケーション・バッファーに戻されるデータは切り捨てられました。数値データ・タイプの場合、数の小数部分は切り捨てられます。時刻およびタイム・スタンプのデータ・タイプの場合、時刻の小数部分は切り捨てられます。
07006 変換が無効です。 結果セットの列のデータ値を、SQLBindCol() 呼び出しの TargetType で指定されたデータ・タイプに変換できませんでした。
07009 記述子索引が無効です。 引き数 Operation は、SQL_REFRESH または SQL_UPDATE で、列は、結果セットの列数より大きい列番号でバインドされました。
21S02 派生表の程度が列リストと一致しません。 引き数 Operation は SQL_UPDATE で、どの列も更新不能でした。理由は、どの列もバインドされていないか、読取専用であるか、バインド済みの長さ / 標識バッファーが SQL_COLUMN_IGNORE であったためです。
22001 ストリング・データの右側が切り捨てられました。 列への文字または 2 進値の割り当てが、非ブランク文字 (文字の場合) または非ヌル文字 (2 進数の場合) またはバイトに切り捨てられました。
22003 数値が範囲外です。 引き数 Operation は SQL_UPDATE で、結果セットの列への数値割り当てが、数の整数部分 (小数部分ではなく) を切り捨てました。

引き数 Operation は SQL_REFRESH で、 1 つまたは複数のバインド済み列に数値を戻したことで、有効数字を失った可能性があります。

22007 日時形式が無効です。 引き数 Operation は SQL_UPDATE で、結果セットの列への日付またはタイム・スタンプ値の割り当てで、年、月、または日フィールドの範囲が超過しました。

引き数 Operation は SQL_REFRESH で、 1 つまたは複数のバインド済み列用の日付またはタイム・スタンプ値の戻りで、年、月、または日フィールドの範囲が超過した可能性があります。

22008 日時フィールドがオーバーフローしました。 Operation 引き数は SQL_UPDATE で、結果セットの列に送られるデータの日時計算で、結果の日時フィールド (年、月、日、時、分、または秒フィールド) が許容範囲を超えたか、または、グレゴリオ歴に基づく日時の法則に対して無効な値になりました。

Operation 引き数は SQL_REFRESH で、結果セットから検索されるデータの日時計算で、結果の日時フィールド (年、月、日、時、分、または秒フィールド) が許容範囲を超えたか、または、グレゴリオ歴に基づく日時の法則に対して無効な値になりました。

HY000 一般的なエラーです。 特定の SQLSTATE がなかった場合のエラーが発生しました。 SQLGetDiagRec() により *MessageText バッファーに返されたエラー・メッセージに、そのエラーと原因が記述されています。
HY001 メモリーの割り振り失敗です。 DB2 CLI は、この関数の実行または完了をサポートするために必要なメモリーを割り当てられませんでした。
HY008 操作が取り消されました。

非同期処理が StatementHandle に対して使用可能になりました。関数が呼び出され、その実行が完了する前に、 SQLCancel()StatementHandle で呼び出されました。そして、関数が再び StatementHandle で呼び出されました。

関数が呼び出され、その実行が完了する前に、 SQLCancel() が複数スレッドのアプリケーション内の別のスレッドから、 StatementHandle で呼び出されました。

HY010 関数の順序エラーです。 指定した StatementHandle が実行状態にありませんでした。最初に SQLExecDirect()SQLExecute()、またはカタログ関数を呼び出さずに、この関数を呼び出しました。

非同期実行関数 (この関数ではない) が StatementHandle で呼び出され、この関数は、呼び出し時に依然実行中でした。

SQLExecute()SQLExecDirect()、または SQLSetPos()StatementHandle で呼び出され、 SQL_NEED_DATA を戻しました。データがすべての実行時データ・パラメーターまたは列用に送られる前に、この関数が呼び出されました。

SQLFetchScroll() が呼び出される前に、または SQLFetch() が呼び出された後で、しかも SQLFreeStmt() が SQL_CLOSE オプションで呼び出された後に、バージョン 2 DB2 CLI アプリケーションが StatementHandleSQLSetPos() を呼び出しました。

HY011 この段階で操作は無効です。 バージョン 2 DB2 CLI アプリケーションが SQL_ATTR_ROW_STATUS_PTR ステートメント属性を設定し、 SQLSetPos() が、SQLFetch()SQLFetchScroll()、または SQLExtendedFetch() の呼び出し前に呼び出されました。
HY090 ストリングまたはバッファー長が無効です。 Operation 引き数は SQL_ADD、SQL_UPDATE、または SQL_UPDATE_BY_BOOKMARK であり、データ値はヌル・ポインターであり、列長値は 0、 SQL_DATA_AT_EXEC、SQL_COLUMN_IGNORE、 SQL_NULL_DATA のいずれでもでないか、または SQL_LEN_DATA_AT_EXEC_OFFSET 以下でした。

Operation 引き数は SQL_ADD、SQL_UPDATE、または SQL_UPDATE_BY_BOOKMARK であり、データ値はヌル・ポインターでなく、列長値は 0 よりも小さいが、SQL_DATA_AT_EXEC、 SQL_COLUMN_IGNORE、 SQL_NTS、または SQL_NULL_DATA ではないか、または SQL_LEN_DATA_AT_EXEC_OFFSET 以下でした。

長さ / 標識バッファーの値は SQL_DATA_AT_EXEC でした。 SQL タイプは、SQL_LONGVARCHAR、SQL_LONGVARBINARY、または他のデータ・ソース固有のデータ・タイプでした。また、SQLGetInfo() の情報タイプ SQL_NEED_LONG_DATA_LEN は "Y" でした。

HY092 オプション・タイプが範囲外です。 Operation 引き数は SQL_UPDATE_BY_BOOKMARK、 SQL_DELETE_BY_BOOKMARK、または SQL_REFRESH_BY_BOOKMARK で、 SQL_ATTR_USE_BOOKMARKS ステートメント属性は SQL_UB_OFF に設定されました。
HY107 行の値が範囲外です。 引き数 RowNumber の指定値は、行セットの行数より大きい値でした。
HY109 カーソル位置が無効です。 StatementHandle に関連したカーソルは、前方向のみで定義されており、行セット内に置くことができませんでした。 SQLSetStmtAttr() の SQL_ATTR_CURSOR_TYPE 属性の説明を参照してください。

Operation 引き数は SQL_UPDATE、SQL_DELETE、または SQL_REFRESH で、 RowNumber 引き数で識別する行は、削除されているか、取り出されていません。

RowNumber 引き数は 0 で、Operation 引き数は SQL_POSITION でした。

HYC00 ドライバーが機能していません。 DB2 CLI またはデータ・ソースは、 Operation 引き数または LockType 引き数で要求した操作をサポートしていません。
HYT00 タイムアウト期間が満了しました。 データ・ソースが結果セットを戻す前に、照会タイムアウト期間が満了しました。タイムアウト期間は、 SQL_ATTR_QUERY_TIMEOUT の Attribute を指定した SQLSetStmtAttr() を通じて設定します。

制約

なし。

CLI サンプル tbread.c

(ここで完全サンプル tbread.c を使用することもできます 。)

/* From the CLI sample TBREAD.C */
/* ... */
    sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); 
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind);
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLSetStmtAttr( hstmt,
                         SQL_ATTR_FETCH_BOOKMARK_PTR, 
                         (SQLPOINTER) bookmark.val, 
                         0);
    STMT_HANDLE_CHECK( hstmt, sqlrc); 
    
/* ... */
    sqlrc = SQLSetPos( hstmt, 3, SQL_POSITION, SQL_LOCK_NO_CHANGE); 
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLGetData(hstmt, 0, SQL_C_LONG, bookmark.val, 4, &bookmark.ind);
    STMT_HANDLE_CHECK( hstmt, sqlrc);    
    sqlrc = SQLSetStmtAttr( hstmt,
                         SQL_ATTR_FETCH_BOOKMARK_PTR, 
                         (SQLPOINTER) bookmark.val, 
                         0);
    STMT_HANDLE_CHECK( hstmt, sqlrc); 
    
 

参照


[ ページのトップ | 前ページ | 次ページ | 目次 | 索引 ]