共用方式為


數據表值參數和數據行值的系結和數據傳輸

適用於: SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics 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 驅動程式,當透過 SQLSetDescField 設定 TVP 名稱與SQL_CA_SS_TYPE_NAME描述元字段時,unixODBC 不會根據稱為 (SQLSetDescFieldA / SQLSetDescFieldW) 的確切函數自動轉換 ANSI 和 Unicode 字符串。 您必須一律使用 SQLBindParameter 或 SQLSetDescFieldW 搭配 Unicode (UTF-16) 字串來設定 TVP 名稱。

數據表值參數本身不會傳送或接收實際數據,但會針對每個組成數據行傳送和接收數據。 因為數據表值參數是虛擬數據行,因此 SQLBindParameter 的參數會參考與其他數據類型不同的屬性,如下所示:

參數 非數據表值參數類型的相關屬性,包括數據行 數據表值參數的相關屬性
InputOutputType IPD 中的SQL_DESC_PARAMETER_TYPE。

對於數據表值參數數據行,這必須與數據表值參數本身的設定相同。
IPD 中的SQL_DESC_PARAMETER_TYPE。

這必須是SQL_PARAM_INPUT。
ValueType SQL_DESC_TYPE,在APD中SQL_DESC_CONCISE_TYPE。 SQL_DESC_TYPE,在APD中SQL_DESC_CONCISE_TYPE。

這必須是SQL_C_DEFAULT或SQL_C_BINARY。
ParameterType SQL_DESC_TYPE,IPD 中的SQL_DESC_CONCISE_TYPE。 SQL_DESC_TYPE,IPD 中的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 時指定資料表值參數類型名稱時,它必須指定為 Unicode 值,即使在建置為 ANSI 應用程式的應用程式中也是如此。 參數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。

對於數據表值參數,這是數據列計數,而不是數據長度。

數據表值參數支援兩種數據傳輸模式:固定數據列系結和變數數據列系結。

已修正數據表值參數數據列系結

對於固定數據列系結,應用程式會配置足以容納所有可能輸入數據行值的緩衝區(或緩衝區陣列)。 應用程式會執行下列動作:

  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. 沒有 數據列的數據表值參數StrLen_or_IndPtr或SQL_DESC_OCTET_LENGTH_PTR設定為SQL_DEFAULT_PARAM,或如果數據表值參數具有數據列,則會在下一次 SQLExecute 或 SQLExecDirect 呼叫時傳送數據列數目。 StrLen_or_IndPtr或SQL_DESC_OCTET_LENGTH_PTR無法設定為數據表值參數的SQL_NULL_DATA,因為數據表值參數不可為 Null(雖然數據表值參數組成數據行可以是可為 Null 的)。 如果此值設定為無效的值,SQLExecute 或 SQLExecDirect 會傳回SQL_ERROR,而診斷記錄會以 SQLSTATE=HY090 產生,而訊息「參數 p> 的字元串或緩衝區長度無效」,其中 p 是參數<編號。

  5. 呼叫 SQLExecute 或 SQLExecDirect。

    如果 數據行的輸入 數據表值參數數據行值設定為 SQL_LEN_DATA_AT_EXEC(length) 或SQL_DATA_AT_EXEC,則可以分次傳入StrLen_or_IndPtr。 這類似於使用參數陣列時,以片段方式傳遞值。 如同所有執行中數據參數,SQLParamData 不會指出驅動程式要求數據的數位數據列;應用程式必須處理此情況。 應用程式無法假設驅動程式要求值的順序。

變數數據表值參數數據列系結

針對變數數據列系結,數據列會在運行時間以批次方式傳送,而應用程式會視需要將數據列傳遞至驅動程式。 這類似於個別參數值的數據執行中。 針對變數數據列系結,應用程式會執行下列動作:

  1. 係結參數和數據表值參數數據行,如上一節的步驟 1 至 3 所述。

  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 數據表值參數的數據表值參數數據列數據,如果數據表值參數沒有數據列,則應用程式會呼叫 sqlPutData ,並將StrLen_or_Ind 設定為 SQL_DEFAULT_PARAM。

    針對非 NULL TVP,應用程式:

    • 所有數據表值參數數據行的Str_Len_or_Ind 設定為適當的值,並針對不是執行中數據參數的數據表值參數數據行填入數據緩衝區。 您可以使用數據表值參數數據行的數據執行中,其方式與一般參數可以分項傳遞至驅動程式的方式類似。

    • 呼叫 SQLPutData, 並將 Str_Len_or_Ind 設定為要傳送至伺服器的數據列數目。 超出範圍 0 或SQL_DESC_ARRAY_SIZE或SQL_DEFAULT_PARAM的任何值都是錯誤,並傳回 SQLSTATE HY090,訊息為「字串或緩衝區長度無效」。0 表示所有數據列都已傳送,而且數據表值參數沒有其他數據(如這份清單中的第二個專案符號專案所述)。 SQL_DEFAULT_PARAM只能在驅動程式第一次要求數據表值參數的數據時使用(如這份清單中的第一個專案符號專案所述)。

  5. 傳送所有數據列時,請呼叫具有 Str_Len_or_Ind 值為 0 之數據表值參數的 SQLPutData,然後繼續進行上述步驟 3a。

  6. 再次呼叫 SQLParamData。 如果數據表值參數數據行之間有任何數據執行中參數,這些參數會由 SQLParamData 傳回的值 ValuePtrPtr 來識別。 當所有數據行值都可供使用時,SQLParamData 會 傳回數據表值參數的 ParameterValuePtr 值,而應用程式會再次開始。

下一步

數據表值參數 ODBC