Share via


Bindung und Datenübertragung von Tabellenwertparametern und Spaltenwerten

Gilt für:SQL ServerAzure SQL-DatenbankAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)

Tabellenwertparameter (Table Valued Parameters, TVP) müssen wie andere Parameter gebunden werden, bevor sie an den Server übergeben werden. Die Anwendung bindet Tabellenwertparameter auf die gleiche Weise, wie sie andere Parameter bindet: mithilfe von SQLBindParameter oder entsprechenden Aufrufen von SQLSetDescField oder SQLSetDescRec. Tabellenwertparameter haben den Serverdatentyp SQL_SS_TABLE. Der C-Typ kann entweder als SQL_C_DEFAULT oder SQL_C_BINARY angegeben werden.

In SQL Server 2008 (10.0.x) oder höher werden nur Eingabetabellenwertparameter unterstützt. Daher gibt jeder Versuch, SQL_DESC_PARAMETER_TYPE auf einen anderen Wert als SQL_PARAM_INPUT festzulegen, SQL_ERROR mit SQLSTATE = HY105 und der Meldung "Ungültiger Parametertyp" zurück.

Gesamten Tabellenwertparameter-Spalten können mit dem Attribut SQL_CA_SS_COL_HAS_DEFAULT_VALUE Standardwerte zugewiesen werden. Einzelne Tabellenwertparameterspaltenwerte können jedoch keine Standardwerte zugewiesen werden, indem SQL_DEFAULT_PARAM in StrLen_or_IndPtr mit SQLBindParameter verwendet wird. Tabellenwertparameter als Ganzes können nicht mithilfe von SQL_DEFAULT_PARAM in StrLen_or_IndPtr mit SQLBindParameter auf einen Standardwert festgelegt werden. Wenn diese Regeln nicht befolgt werden, gibt SQLExecute oder SQLExecDirect SQL_ERROR zurück. Ein Diagnosedatensatz wird mit SQLSTATE=07S01 und der Meldung "Ungültige Verwendung des Standardparameters für Parameter <p>" generiert, wobei <p> die Ordnungszahl des TVP in der Abfrageanweisung ist.

Hinweis

Tabellenwertparameter verfügen nicht über einen Standardwert, der festgelegt werden kann, da SQL_DEFAULT_PARAM keine Zeilen angibt. Wenn also keine Zeilen vorhanden sind, müssen keine Spalten gebunden werden.

Nachdem die Anwendung den Tabellenwertparameter gebunden hat, muss sie jede einzelne Tabellenwertparameter-Spalte binden. Dazu ruft die Anwendung zunächst SQLSetStmtAttr auf, um SQL_SOPT_SS_PARAM_FOCUS auf die Ordnungszahl eines Tabellenwertparameters festzulegen. Die Anwendung bindet die Spalten des Tabellenwertparameters durch Aufrufe an die folgenden Routinen: SQLBindParameter, SQLSetDescRec und SQLSetDescField. Wenn Sie SQL_SOPT_SS_PARAM_FOCUS auf 0 festlegen, wird der übliche Effekt von SQLBindParameter, SQLSetDescRec und SQLSetDescField beim Arbeiten mit regulären Parametern der obersten Ebene wiederhergestellt.

Hinweis

Für die Linux- und Mac-ODBC-Treiber mit unixODBC 2.3.1 bis 2.3.4 konvertiert unixODBC beim Festlegen des TVP-Namens über SQLSetDescField mit dem Feld SQL_CA_SS_TYPE_NAME Deskriptor nicht automatisch zwischen ANSI- und Unicode-Zeichenfolgen, abhängig von der genauen Funktion namens (SQLSetDescFieldA/SQLSetDescFieldW). Es ist erforderlich, immer SQLBindParameter oder SQLSetDescFieldW mit einer Unicode-Zeichenfolge (UTF-16) zu verwenden, um den TVP-Namen festzulegen.

Für den Tabellenwertparameter an sich werden keine Daten gesendet oder empfangen, die Daten werden für die einzelnen Spalten, aus denen er sich zusammensetzt, gesendet und empfangen. Da der Tabellenwertparameter eine Pseudospalte ist, beziehen sich die Parameter für SQLBindParameter wie folgt auf andere Attribute als andere Datentypen:

Parameter Verwandtes Attribut für Parametertypen ohne Tabellenwert, einschließlich Spalten Verknüpftes Attribut für Tabellenwertparameter
InputOutputType SQL_DESC_PARAMETER_TYPE in IPD

Für Tabellenwertparameter-Spalten muss diese Angabe der Angabe für den Tabellenwertparameter selbst entsprechen.
SQL_DESC_PARAMETER_TYPE in IPD

Hier muss SQL_PARAM_INPUT angegeben werden.
ValueType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in APD SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in APD

Hier muss SQL_C_DEFAULT oder SQL_C_BINARY angegeben werden.
ParameterType SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in IPD SQL_DESC_TYPE, SQL_DESC_CONCISE_TYPE in IPD

Hier muss SQL_SS_TABLE angegeben werden.
ColumnSize SQL_DESC_LENGTH oder SQL_DESC_PRECISION in IPD

Dies hängt vom Wert von ParameterType ab.
SQL_DESC_ARRAY_SIZE

Kann auch mit SQL_ATTR_PARAM_SET_SIZE festgelegt werden, wenn der Parameterfokus auf den Tabellenwertparameter festgelegt wurde.

Bei einem Tabellenwertparameter ist dies die Anzahl von Zeilen in den Tabellenwertparameter-Spaltenpuffern.
DecimalDigits SQL_DESC_PRECISION oder SQL_DESC_SCALE in IPD Nicht verwendet. Diese Angabe muss 0 sein.

Wenn dieser Parameter nicht 0 ist, gibt SQLBindParameter SQL_ERROR zurück, und ein Diagnosedatensatz wird mit SQLSTATE= HY104 und der Meldung "Ungültige Genauigkeit oder Skalierung" generiert.
ParameterValuePtr SQL_DESC_DATA_PTR in APD SQL_CA_SS_TYPE_NAME

Dies ist für Aufrufe gespeicherter Prozeduren optional, und NULL kann angegeben werden, wenn dies nicht erforderlich ist. Er muss für SQL-Anweisungen angegeben werden, die keine Prozeduraufrufe sind.

Dieser Parameter dient als eindeutiger Wert, anhand dessen die Anwendung den betreffenden Tabellenwertparameter bei Verwendung einer variablen Zeilenbindung identifizieren kann. Weitere Informationen finden Sie im Abschnitt "Variable Tabellenwertparameter-Zeilenbindung" weiter unten in diesem Thema.

Wenn ein Tabellenwertparametertypname bei einem Aufruf von SQLBindParameter angegeben wird, muss er als Unicode-Wert angegeben werden, auch in Anwendungen, die als ANSI-Anwendungen erstellt wurden. Der für den Parameter StrLen_or_IndPtr verwendete Wert sollte entweder SQL_NTS oder die Zeichenfolgenlänge des Namens multipliziert mit der Größe von (WCHAR) sein.
BufferLength SQL_DESC_OCTET_LENGTH in APD Die Länge des Typnamens des Tabellenwertparameters in Byte

Dies kann SQL_NTS sein, wenn der Typname NULL-beendet ist, oder 0, wenn der Name des Tabellenwertparametertyps nicht erforderlich ist.
StrLen_or_IndPtr SQL_DESC_OCTET_LENGTH_PTR in APD SQL_DESC_OCTET_LENGTH_PTR in APD

Für Tabellenwertparameter wird hier die Zeilenanzahl statt die Datenlänge angegeben.

Zwei Datenübertragungsmodi werden für Tabellenwertparameter unterstützt: feste Zeilenbindung und variable Zeilenbindung.

Feste Tabellenwertparameter-Zeilenbindung

Bei der festen Zeilenbindung ordnet die Anwendung Puffer (oder Pufferarrays) zu, die groß genug sind, um alle Eingabespaltenwerte aufnehmen zu können. Die Anwendung führt Folgendes aus:

  1. Bindet alle Parameter mithilfe von SQLBindParameter-, SQLSetDescRec- oder SQLSetDescField-Aufrufen.

    1. Sie legt SQL_DESC_ARRAY_SIZE auf die maximale Anzahl von Zeilen fest, die für jeden Tabellenwertparameter übertragen werden können. Dies kann im SQLBindParameter-Aufruf erfolgen.
  2. Ruft SQLSetStmtAttr auf, um SQL_SOPT_SS_PARAM_FOCUS auf die Ordnungszahl jedes Tabellenwertparameters festzulegen.

    1. Bindet für jeden Tabellenwertparameter Tabellenwertparameterspalten mithilfe von SQLBindParameter-, SQLSetDescRec- oder SQLSetDescField-Aufrufen.

    2. Ruft für jede Tabellenwertparameterspalte, die Standardwerte aufweisen soll, SQLSetDescField auf, um SQL_CA_SS_COL_HAS_DEFAULT_VALUE auf 1 festzulegen.

  3. Ruft SQLSetStmtAttr auf, um SQL_SOPT_SS_PARAM_FOCUS auf 0 festzulegen. Dies muss vor dem Aufruf von SQLExecute oder SQLExecDirect erfolgen. Andernfalls wird SQL_ERROR zurückgegeben, und ein Diagnosedatensatz wird mit SQLSTATE=HY024 und der Meldung "Ungültiger Attributwert, SQL_SOPT_SS_PARAM_FOCUS (muss zur Ausführungszeit null sein)" generiert.

  4. Legt StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR auf SQL_DEFAULT_PARAM für einen Tabellenwertparameter ohne Zeilen oder die Anzahl der Zeilen fest, die beim nächsten Aufruf von SQLExecute oder SQLExecDirect übertragen werden sollen, wenn der Tabellenwertparameter Zeilen enthält. StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR kann für einen Tabellenwertparameter nicht auf SQL_NULL_DATA festgelegt werden, da Tabellenwertparameter nicht NULL-werte zulassen können (obwohl Tabellenwertparameter-Konstituierende Spalten möglicherweise NULL-Werte zulassen können). Wenn dies auf einen ungültigen Wert festgelegt ist, gibt SQLExecute oder SQLExecDirect SQL_ERROR zurück, und ein Diagnosedatensatz wird mit SQLSTATE=HY090 und der Meldung "Ungültige Zeichenfolge oder Pufferlänge für Parameter <p>" generiert, wobei p die Parameternummer ist.

  5. Ruft SQLExecute oder SQLExecDirect auf.

    Spaltenwerte von Tabellenwertparametern können in Teilen übergeben werden, wenn StrLen_or_IndPtr auf SQL_LEN_DATA_AT_EXEC(Länge) oder SQL_DATA_AT_EXEC für die Spalte festgelegt ist. Dies gleicht der Übergabe einzelner Werte bei Verwendung von Parameterarrays. Wie bei allen Datenausführungsparametern gibt SQLParamData nicht an, für welche Zeile des Arrays der Treiber Daten anfordert. die Anwendung muss sich darum kümmern. Die Anwendung kann keine Annahmen über die Reihenfolge treffen, in der der Treiber Werte anfordert.

Variable Tabellenwertparameter-Zeilenbindung

Bei der Variablenzeilenbindung werden Zeilen zur Ausführungszeit in Batches übertragen, und die Anwendung übergibt Zeilen bei Bedarf an den Treiber. Dies ähnelt der Übergabe einzelner Werte für Data-at-Execution-Parameter zur Laufzeit. Bei einer variablen Zeilenbindung geht die Anwendung wie folgt vor:

  1. Bindet Parameter und Tabellenwertparameterspalten, wie in den Schritten 1 bis 3 des vorherigen Abschnitts beschrieben, "Fixed Table-Valued Parameter Row Binding".

  2. Legt StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR für alle Tabellenwertparameter fest, die zur Ausführungszeit an SQL_DATA_AT_EXEC übergeben werden sollen. Wenn keiner festgelegt ist, wird der Parameter wie im vorherigen Abschnitt beschrieben verarbeitet.

  3. Ruft SQLExecute oder SQLExecDirect auf. Dadurch wird SQL_NEED_DATA zurückgegeben, wenn es SQL_PARAM_INPUT oder SQL_PARAM_INPUT_OUTPUT Parameter gibt, die als Data-at-Execution-Parameter behandelt werden sollen. In diesem Fall geht die Anwendung wie folgt vor:

    • Ruft SQLParamData auf. Dadurch wird der ParameterValuePtr-Wert für einen Data-at-Execution-Parameter und ein Rückgabecode von SQL_NEED_DATA zurückgegeben. Wenn alle Parameterdaten an den Treiber übergeben wurden, gibt SQLParamData SQL_SUCCESS, SQL_SUCCESS_WITH_INFO oder SQL_ERROR zurück. Bei Datenausführungsparametern kann ParameterValuePtr, der mit dem Deskriptorfeld SQL_DESC_DATA_PTR identisch ist, als Token betrachtet werden, um einen Parameter zu identifizieren, für den ein Wert eindeutig erforderlich ist. Dieses "Token" wird beim Binden von der Anwendung an den Treiber übergeben und während der Ausführung dann wieder an die Anwendung übergeben.
  4. Wenn der Tabellenwertparameterparameter-Zeilendaten für NULL-Tabellenwertparameter sendet, ruft eine Anwendung SQLPutData auf, wenn der Tabellenwertparameter keine Zeilen enthält, mit StrLen_or_Ind auf SQL_DEFAULT_PARAM festgelegt ist.

    Bei Tabellenwertparametern, die nicht NULL sind, geht die Anwendung wie folgt vor:

    • Legt Str_Len_or_Ind für alle Tabellenwertparameterspalten auf entsprechende Werte fest und füllt Datenpuffer für Tabellenwertparameterspalten auf, bei denen es sich nicht um Data-at-Execution-Parameter handelt. Tabellenwertparameter-Spalten können Daten zur Laufzeit auf ähnliche Weise übergeben werden wie dem Treiber gewöhnliche Parameter schrittweise übergeben werden.

    • Ruft SQLPutData auf , wobei Str_Len_or_Ind auf die Anzahl der Zeilen festgelegt ist, die an den Server gesendet werden sollen. Jeder Wert außerhalb des Bereichs 0 bis SQL_DESC_ARRAY_SIZE oder SQL_DEFAULT_PARAM ist ein Fehler und gibt SQLSTATE HY090 mit der Meldung "Ungültige Zeichenfolge oder Pufferlänge" zurück. 0 gibt an, dass alle Zeilen gesendet wurden, und es gibt keine weiteren Daten für einen Tabellenwertparameter (wie im zweiten Aufzählungszeichen in dieser Liste angegeben). SQL_DEFAULT_PARAM kann nur verwendet werden, wenn der Treiber zum ersten Mal Daten für einen Tabellenwertparameter anfordert (wie im ersten Aufzählungspunkt dieser Auflistung beschrieben).

  5. Wenn alle Zeilen gesendet wurden, ruft SQLPutData für den Tabellenwertparameter mit dem Str_Len_or_Ind Wert 0 auf, und fahren Sie dann mit Schritt 3a oben fort.

  6. Ruft SQLParamData erneut auf. Wenn datenbasierte Parameter in den Tabellenwertparameterspalten vorhanden sind, werden diese durch den Wert ValuePtrPtrPtr identifiziert, der von SQLParamData zurückgegeben wird. Wenn alle Spaltenwerte verfügbar sind, gibt SQLParamData den ParameterValuePtr-Wert für den Tabellenwertparameter zurück, und die Anwendung beginnt erneut.

Nächste Schritte

Tabellenwertparameter ODBC