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

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

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

SQL Server 2008 (10.0.x) 以降では、入力テーブル値パラメーターのみがサポートされます。 したがって、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を返します。 診断レコードは SQLSTATE=07S01 で生成され、"パラメーター <p> の既定のパラメーターの使用が無効です" というメッセージが表示されます。ここで <、p> はクエリ ステートメントの TVP の序数です。

注意

SQL_DEFAULT_PARAMは行を示さないため、テーブル値パラメーターには設定できる既定値がありません。 そのため、行がない場合は、バインドする列はありません。

テーブル値パラメーターをバインドしたら、アプリケーションでは、次に、テーブル値パラメーターの各列をバインドする必要があります。 これを行うには、アプリケーションは最初に SQLSetStmtAttr を呼び出して、テーブル値パラメーターの序数にSQL_SOPT_SS_PARAM_FOCUSを設定します。 アプリケーションは、SQLBindParameter、SQLSetDescRec、SQLSetDescField の各ルーチンの呼び出しによって、テーブル値パラメーターの列をバインドします。 SQL_SOPT_SS_PARAM_FOCUS を 0 に設定すると、通常の最上位パラメーターで動作する SQLBindParameter、SQLSetDescRec、SQLSetDescField の通常の効果が復元されます。

注意

unixODBC 2.3.1 から 2.3.4 の Linux および Mac ODBC ドライバーの場合、SQL_CA_SS_TYPE_NAME記述子フィールドを使用して SQLSetDescField を使用して TVP 名を設定する場合、unixODBC は、(SQLSetDescFieldA/ SQLSetDescFieldW) と呼ばれる正確な関数に応じて ANSI 文字列と Unicode 文字列の間で自動的に変換されません。 TVP 名を設定するには、常に SQLBindParameter または SQLSetDescFieldW を Unicode (UTF-16) 文字列で使用する必要があります。

テーブル値パラメーター自体の実際のデータは送受信されませんが、テーブル値パラメーターを構成する各列のデータは送受信されます。 テーブル値パラメーターは擬似列であるため、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するか、名前の文字列長にサイズ (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. SQLBindParameter、SQLSetDescRec、または SQLSetDescField 呼び出しを使用して、すべてのパラメーターをバインドします。

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

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

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

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

  4. 行のないテーブル値パラメーターのSQL_DEFAULT_PARAM 、またはテーブル 値パラメーターに行がある場合は SQLExecute または SQLExecDirect の次の呼び出しで転送される行の数をStrLen_or_IndPtrまたはSQL_DESC_OCTET_LENGTH_PTRに設定します。 StrLen_or_IndPtr またはSQL_DESC_OCTET_LENGTH_PTRをテーブル値パラメーターのSQL_NULL_DATAに設定することはできません。テーブル値パラメーターは null 許容ではありません (ただし、テーブル値パラメーター構成列は null 許容である可能性があります)。 これが無効な値に設定されている場合、SQLExecute または SQLExecDirect はSQL_ERRORを返し、SQLSTATE=HY090 とメッセージ "Invalid string or buffer length for parameter p>" (p はパラメーター<番号) で診断レコードが生成されます。

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

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

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

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

  1. 前のセクションの手順 1 から 3 の「パラメーター行バインドを修正しました」で説明したように、パラメーターとテーブル値パラメーター列Table-Valuedバインドします。

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

  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 を適切な値に設定し、実行時データ パラメーターではないテーブル値パラメーター列のデータ バッファーを設定します。 通常のパラメーターを個別にドライバーに渡すことができるように、テーブル値パラメーターの列の実行時データを使用することができます。

    • sqlPutData を呼び出 し、Str_Len_or_Ind サーバーに送信する行数に設定します。 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 値を返し、アプリケーションが再び開始されます。

次の手順

テーブル値パラメーター ODBC