次の方法で共有


テーブル値パラメーターおよび列の値のバインドとデータ転送

テーブル値パラメーターは、他のパラメーターと同様、サーバーに渡す前にバインドする必要があります。アプリケーションでは、他のパラメーターと同じように、SQLBindParameter、または同等の SQLSetDescFieldSQLSetDescRec を呼び出すことにより、テーブル値パラメーターをバインドします。テーブル値パラメーター用のサーバーのデータ型は SQL_SS_TABLE です。C 型は SQL_C_DEFAULT または SQL_C_BINARY として指定できます。

SQL Server 2008 以降では、入力のテーブル値パラメーターのみがサポートされています。そのため、SQL_DESC_PARAMETER_TYPE に SQL_PARAM_INPUT 以外の値を設定しようとすると、SQLSTATE = HY105 の SQL_ERROR が発生し、"パラメーターの型が無効です。" というメッセージが返されます。

属性 SQL_CA_SS_COL_HAS_DEFAULT_VALUE を使用すると、テーブル値パラメーターのすべての列に既定値を割り当てることができます。ただし、SQLBindParameter で StrLen_or_IndPtr に SQL_DEFAULT_PARAM を使用しても、テーブル値パラメーターの各列の値に既定値を割り当てることはできません。また SQLBindParameter で StrLen_or_IndPtr に SQL_DEFAULT_PARAM を使用しても、テーブル値パラメーター全体に既定値を設定することはできません。これらの規則に従わない場合、SQLExecute または SQLExecDirect が SQL_ERROR を返し、"パラメーター <p> に既定のパラメーターを使用できません" というメッセージを含む、SQLSTATE=07S01 の診断レコードが生成されます。<p> は、クエリ ステートメントにおける TVP の序数です。

テーブル値パラメーターをバインドしたら、アプリケーションでは、次に、テーブル値パラメーターの各列をバインドする必要があります。これを行うには、アプリケーションで、まず SQLSetStmtAttr を呼び出し、テーブル値パラメーターの序数に SQL_SOPT_SS_PARAM_FOCUS を設定します。次に、SQLBindParameterSQLSetDescRec、および SQLSetDescField の各ルーチンを呼び出して、テーブル値パラメーターの列をバインドします。SQL_SOPT_SS_PARAM_FOCUS を 0 に設定すると、標準の最上位パラメーターを使用する際に SQLBindParameterSQLSetDescRecSQLSetDescField と同じ効果が復元されます。

テーブル値パラメーター自体の実際のデータは送受信されませんが、テーブル値パラメーターを構成する各列のデータは送受信されます。テーブル値パラメーターは擬似列なので、SQLBindParameter のパラメーターは、次のように、他のデータ型とは異なる属性を参照するために使用されます。

パラメーター

テーブル値パラメーター以外のパラメーター (列など) に関連する属性

テーブル値パラメーターに関連する属性

InputOutputType

IPD の SQL_DESC_PARAMETER_TYPE。

テーブル値パラメーターの列の場合、これはテーブル値パラメーター自体の設定と同じである必要があります。

IPD の SQL_DESC_PARAMETER_TYPE。

これは SQL_PARAM_INPUT である必要があります。

ValueType

APD の SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE。

APD の SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE。

これは SQL_C_DEFAULT または SQL_C_BINARY である必要があります。

ParameterType

IPD の SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE。

IPD の SQL_DESC_TYPE、SQL_DESC_CONCISE_TYPE。

これは SQL_SS_TABLE である必要があります。

ColumnSize

IPD の SQL_DESC_LENGTH または SQL_DESC_PRECISION。

これは ParameterType の値によって異なります。

SQL_DESC_ARRAY_SIZE。

テーブル値パラメーターにフォーカスが設定されている場合は SQL_ATTR_PARAM_SET_SIZE を使用して設定することもできます。

テーブル値パラメーターの場合、これはテーブル値パラメーターの列バッファー内の行数です。

DecimalDigits

IPD の SQL_DESC_PRECISION または SQL_DESC_SCALE。

使用しません。これは 0 である必要があります。

このパラメーターが 0 でない場合、SQLBindParameter は SQL_ERROR を返し、"有効桁数または小数点以下桁数が無効です" というメッセージを含む SQLSTATE= HY104 の診断レコードが生成されます。

ParameterValuePtr

APD の SQL_DESC_DATA_PTR。

SQL_CA_SS_TYPE_NAME。

これは、ストアド プロシージャの呼び出しでは省略可能で、不要の場合は NULL を指定できます。プロシージャの呼び出し以外の SQL ステートメントでは、指定する必要があります。

このパラメーターは、可変の行バインドの使用時にアプリケーションがテーブル値パラメーターを特定するための一意の値としても機能します。詳細については、「テーブル値パラメーターの可変の行バインド」を参照してください。

テーブル値パラメーターの型名を SQLBindParameter の呼び出しで指定する場合、ANSI アプリケーションとしてビルドされているアプリケーションであっても、Unicode 値として指定する必要があります。パラメーター StrLen_or_IndPtr に使用する値は、SQL_NTS であるか、または名前の文字列長に sizeof(WCHAR) を掛けた値である必要があります。

BufferLength

APD の SQL_DESC_OCTET_LENGTH。

テーブル値パラメーターの型名の長さ (バイト単位)。

型名が NULL 終端の場合は SQL_NTS に、テーブル値パラメーターの型名が不要の場合は 0 になります。

StrLen_or_IndPtr

APD の SQL_DESC_OCTET_LENGTH_PTR。

APD の SQL_DESC_OCTET_LENGTH_PTR。

テーブル値パラメーターの場合、これはデータ長ではなく行数です。

テーブル値パラメーターでは、固定の行バインドと可変の行バインドという 2 つのデータ転送モードがサポートされています。

テーブル値パラメーターの固定の行バインド

固定の行バインドの場合、アプリケーションでは、使用可能なすべての入力列の値に対して十分な大きさのバッファー (バッファー配列) を割り当てます。このアプリケーションによって次の処理が行われます。

  1. SQLBindParameterSQLSetDescRec、または SQLSetDescField の呼び出しを使用して、すべてのパラメーターをバインドします。

    1. SQL_DESC_ARRAY_SIZE に各テーブル値パラメーターの転送可能な最大行数を設定します。これは、SQLBindParameter の呼び出しで行うことができます。
  2. SQLSetStmtAttr を呼び出して、SQL_SOPT_SS_PARAM_FOCUS に各テーブル値パラメーターの序数を設定します。

    1. テーブル値パラメーターごとに、SQLBindParameterSQLSetDescRec、または SQLSetDescField の呼び出しを使用して、テーブル値パラメーターの列をバインドします。

    2. 既定値を指定するテーブル値パラメーターの列ごとに、SQLSetDescField を呼び出して SQL_CA_SS_COL_HAS_DEFAULT_VALUE に 1 を設定します。

  3. SQLSetStmtAttr を呼び出して SQL_SOPT_SS_PARAM_FOCUS に 0 を設定します。これは、SQLExecute または SQLExecDirect を呼び出す前に行う必要があります。そうしないと、SQL_ERROR が返され、"属性値 SQL_SOPT_SS_PARAM_FOCUS が無効です (実行時に 0 である必要があります)" というメッセージを含む、SQLSTATE=HY024 の診断レコードが生成されます。

  4. StrLen_or_IndPtr または SQL_DESC_OCTET_LENGTH_PTR に、SQL_DEFAULT_PARAM (テーブル値パラメーターに行が存在しない場合) または次回 SQLExecute または SQLExecDirect を呼び出したときに転送する行数 (テーブル値パラメーターに行が存在する場合) を設定します。テーブル値パラメーターを構成する列で NULL 値が許容される場合はありますが、テーブル値パラメーター自体では NULL 値が許容されないため、StrLen_or_IndPtr または SQL_DESC_OCTET_LENGTH_PTR に SQL_NULL_DATA を設定することはできません。これに無効な値が設定されている場合、SQLExecute または SQLExecDirect を呼び出すと、SQL_ERROR が返され、"パラメーター <p> の文字列長またはバッファー長が正しくありません" というメッセージを含む、SQLSTATE=HY090 の診断レコードが生成されます。p はパラメーター番号です。

  5. SQLExecute または SQLExecDirect を呼び出します。

列の StrLen_or_IndPtr に SQL_LEN_DATA_AT_EXEC (length) または SQL_DATA_AT_EXEC が設定されている場合は、入力のテーブル値パラメーターの列の値を個別に渡すことができます。これは、パラメーターの配列を使用するときに値を個別に渡す場合と似ています。実行時データのすべてのパラメーターと同様、SQLParamData は、ドライバーが要求しているデータが配列のどの行にあるかを示しません。そのため、アプリケーションがこれに対処する必要があります。アプリケーションでは、ドライバーが値を要求する順序についてどのような想定も行うことができません。

テーブル値パラメーターの可変の行バインド

可変の行バインドの場合、行は実行時にバッチで転送され、アプリケーションは要求時に行をドライバーに渡します。これは、各パラメーター値の実行時データに似ています。可変の行バインドでは、アプリケーションによって次の処理が行われます。

  1. 前述の「テーブル値パラメーターの固定の行バインド」の手順 1. ~ 3. の説明に従って、パラメーターと、テーブル値パラメーターの列をバインドします。

  2. 実行時に渡されるすべてのテーブル値パラメーターの StrLen_or_IndPtr または SQL_DESC_OCTET_LENGTH_PTR に SQL_DATA_AT_EXEC を設定します。どちらも設定しない場合、前のセクションで説明したように、パラメーターが処理されます。

  3. SQLExecute または SQLExecDirect を呼び出します。実行時データ パラメーターとして処理される SQL_PARAM_INPUT パラメーターまたは SQL_PARAM_INPUT_OUTPUT パラメーターが存在する場合は、SQL_NEED_DATA が返されます。この場合、アプリケーションによって次の処理が行われます。

    • SQLParamData を呼び出します。実行時データ パラメーターの ParameterValuePtr 値と、リターン コード SQL_NEED_DATA が返されます。すべてのパラメーター データがドライバーに渡された場合、SQLParamData によって SQL_SUCCESS、SQL_SUCCESS_WITH_INFO、または SQL_ERROR が返されます。実行時データ パラメーターの ParameterValuePtr は、記述子フィールド SQL_DESC_DATA_PTR と同じであり、値を必要とするパラメーターを一意に識別するためのトークンと見なすことができます。この "トークン" は、バインド時にアプリケーションからドライバーに渡され、実行時にアプリケーションに返されます。
  4. テーブル値パラメーターが NULL の場合にテーブル値パラメーターの行データを送信するには、テーブル値パラメーターに行が存在しない場合は、アプリケーションでは、StrLen_or_Ind に SQL_DEFAULT_PARAM を設定して SQLPutData を呼び出します。

    NULL 以外の TVP については、アプリケーションによって次の処理が行われます。

    • テーブル値パラメーターのすべての列の Str_Len_or_Ind に適切な値を設定し、テーブル値パラメーターの列のうち、実行時データ パラメーターとはならない列のデータ バッファーを設定します。通常のパラメーターを個別にドライバーに渡すことができるように、テーブル値パラメーターの列の実行時データを使用することができます。

    • サーバーに送信する行数を Str_Len_or_Ind に設定して SQLPutData を呼び出します。0 から SQL_DESC_ARRAY_SIZE の範囲を超える値と SQL_DEFAULT_PARAM 以外の値はエラーになります。"文字列長またはバッファー長が正しくありません。" というメッセージを含む SQLSTATE HY090 が返されます。0 は、すべての行が送信済みで、テーブル値パラメーターのデータが存在しないことを示します (この箇条書きの 2 番目の項目参照)。SQL_DEFAULT_PARAM を使用できるのは、ドライバーがテーブル値パラメーターのデータを最初に要求するときだけです (この箇条書きの 1 番目の項目参照)。

  5. すべての行が送信されたら、テーブル値パラメーターに対して、Str_Len_or_Ind 値を 0 に設定した SQLPutData を呼び出し、手順 3a. に進みます。

  6. 再度 SQLParamData を呼び出します。テーブル値パラメーターの列の中に実行時データ パラメーターが含まれる場合、実行時データ パラメーターは、SQLParamData によって返された値 ValuePtrPtr で識別されます。列の値がすべて使用できる場合、SQLParamData が再びテーブル値パラメーターの ParameterValuePtr の値を返し、アプリケーションは再び開始されます。