SQLSetCursorName() - カーソル名を設定する

SQLSetCursorName() は、カーソル名をステートメント・ハンドルに関連付けます。 Db2 ODBC は、各ステートメント・ハンドルが割り振られるたびにカーソル名を暗黙的に生成するため、この機能はオプションです。

SQLSetCursorName() の ODBC 仕様

表 1. SQLSetCursorName() 仕様
ODBC 仕様レベル X/Open CLI CAE 仕様 ISO CLI 仕様
1.0 はい はい

構文

SQLRETURN   SQLSetCursorName (SQLHSTMT          hstmt,
                              SQLCHAR     FAR   *szCursor,
                              SQLSMALLINT       cbCursor);

関数引数

次の表は、この関数のそれぞれの引数ごとに、 データ・タイプ、用途、および説明を示しています。

表 2. SQLSetCursorName() 引数
データ・タイプ 引数 使用 説明
SQLHSTMT hstmt input ステートメント・ハンドル
SQLCHAR * szCursor input カーソル名
SQLSMALLINT cbCursor input 引数 szCursor の内容の長さ (バイト)。

使用法

Db2 ODBC は常に、照会が直接準備または実行される際に内部で生成されるカーソル名を生成して使用します。 SQLSetCursorName() では、アプリケーションで定義されるカーソル名 を SQL ステートメント (位置付け UPDATE または DELETE) で使用できます。 Db2 ODBC は、この名前を内部名にマップします。 この名前はステートメント・ハンドルと関連付けられたままになり、 この状態が続くのは、そのステートメント・ハンドルがドロップされるか、 またはこのステートメント・ハンドルで他の SQLSetCursorName() が呼び出されるまでです。

SQLGetCursorName() はアプリケーションが設定した名前を戻しますが (名前が設定されている場合)、 位置付け UPDATE および DELETE ステートメントに関連したエラー・メッセージでは内部名を参照しています。

推奨事項 : SQLSetCursorName() は使用しないでください。 代わりに、SQLGetCursorName() を呼び出すと取得可能な内部名を使用してください。

カーソル名は、次の規則に従う必要があります。
  • 接続内のすべてのカーソル名はユニークでなければなりません。
  • それぞれのカーソル名の長さは、18 バイト以下でなければなりま せん。 カーソル名を 18 バイトより長く設定しようとすると、そのカーソル名は 18 バイトで切り捨てられます。 (警告は生成されません。)
  • 内部生成される名前は、SQLCUR、SQL_CUR、または SQLCURQRS で始まるため、 アプリケーションでは内部名と同じ名前にならないように、SQLCUR もしくは SQL_CUR で 始まるカーソル名は入力しないでください。
  • SQL では、カーソル名は ID と見なされるため、英字 (a-z、A-Z) で始まり、 その後に数字 (0-9)、英字、または下線文字 (_) の任意の組み合わせが続く必要があります。
  • 上記以外の文字 (例えば、各国語セットの文字または 2 バイト文字セットの文字) を含む カーソル名が使用できるようにするには、アプリケーションでカーソル名を二重引用符 (") で 囲む必要があります。
  • 入力カーソル名が二重引用符で囲まれていない場合は、すべての先行ブランクと後続ブランクは 入力カーソル名ストリングから除去されます。

アプリケーションでは、処理を効率的に行うために、szCursor バッファーには、 先行スペースも後続スペースも入れないようにしてください。 szCursor バッファーが 区切り ID を含む場合、アプリケーションは最初の二重引用符 を szCursor バッファーの最初の文字として配置する必要があります。

戻りコード

SQLSetCursorName() は、呼び出された後、次のいずれかの値を戻します。
  • SQL_SUCCESS
  • SQL_ERROR
  • SQL_INVALID_HANDLE

診断

次の表は、この関数が生成する各 SQLSTATE 値ごとに、 その記述と説明を一覧で記載してあります。

表 3. SQLSetCursorName() SQLSTATE
SQLSTATE 説明 説明
08S01 通信リンク障害が発生しました。 関数が完了する前に、アプリケーションとデータ・ソース間の 通信リンクで障害が発生しました。
34000 カーソル名が無効です。 次の 1 つ以上の理由に該当した場合に、この SQLSTATE が戻されます。
  • 引数 szCursor で指定されたカーソル名は無効です。 カーソル名が SQLCUR、SQL_CUR、または SQLCURQRS の いずれかで始まっているか、カーソル命名規則 (先頭が a から z または A から Z で、 その後に英字、数字、下線 '_' 文字の任意の組み合わせが続く) に違反しています。
  • 引数 szCursor で指定されたカーソル名は、既に存在しています。
  • カーソル名の長さが、SQL_MAX_CURSOR_NAME_LEN 引数を指定した SQLGetInfo() によって戻された値より大きい。
580 04 予想外のシステム障害が発生しました。 リカバリー不能なシステム・エラーです。
HY001 メモリーの割り振りが失敗しました。 DB2 ODBC は、関数の実行または完了をサポートするのに必要なメモリーを割り振ることができません。
HY009 NULL ポインターの使用が無効です。 szCursor が NULL ポインターです。
HY010 関数のシーケンス・エラーです。 次の 1 つ以上の理由に該当した場合に、この SQLSTATE が戻されます。
  • ステートメント・ハンドル上にオープン・カーソルまたは位置指定されたカーソルがあります。
  • この関数は、実行時データの操作時に呼び出されました。 (すなわち、SQLParamData() または SQLPutData() 関数を使用するプロシージャー実行中に関数が呼び出されました。)
HY013 予期しない、メモリーのハンドル・エラーです。 DB2 ODBC は、関数の実行または完了をサポートするのに必要なメモリーにアクセスすることができません。
HY090 ストリングまたはバッファーの長さが無効です。 引数 cbCursor0 より小さい値です が、SQL_NTS と等しくありません。

以下の例は、 SQLSetCursorName() を使用して、 カーソル名を設定するアプリケーションを示しています。
図1: カーソル名を設定するアプリケーション
/* ... */
    SQLCHAR         sqlstmt[] =
                    "SELECT name, job FROM staff "
                    "WHERE job='Clerk'  FOR UPDATE OF job";
/* ... */
    /* Allocate second statement handle for update statement */
    rc2 = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt2);
    /* Set Cursor for the SELECT statement handle */
    rc = SQLSetCursorName(hstmt1, "JOBCURS", SQL_NTS);
    rc = SQLExecDirect(hstmt1, sqlstmt, SQL_NTS);
    /* bind name to first column in the result set */
    rc = SQLBindCol(hstmt1, 1, SQL_C_CHAR, (SQLPOINTER) name.s, 10,
                    &name.ind);
    /* bind job to second column in the result set */
    rc = SQLBindCol(hstmt1, 2, SQL_C_CHAR, (SQLPOINTER) job.s, 6,
                    &job.ind);
    printf("Job change for all clerks\n");
    while ((rc = SQLFetch(hstmt1)) == SQL_SUCCESS) {
        printf("Name: %-9.9s Job: %-5.5s \n", name.s, job.s);
        printf("Enter new job or return to continue\n");
        gets(newjob);
        if (newjob[0] != '\0') {
            sprintf(updstmt,
                    "UPDATE staff set job = '%s' where current of JOBCURS",
                    newjob);
            rc2 = SQLExecDirect(hstmt2, updstmt, SQL_NTS);
        }
    }
    if (rc != SQL_NO_DATA_FOUND)
        check_error(henv, hdbc, hstmt1, rc, __LINE__, __FILE__);
/* ... */