Freigeben über


Bindung und Datenübertragung von Tabellenwertparametern und Spaltenwerten

Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW)

Tabellenwertparameter (TVP) müssen wie andere Parameter gebunden werden, bevor sie an den Server übergeben werden. Die Anwendung bindet Tabellenwertparameter auf die gleiche Weise wie andere Parameter: 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. Einzelnen Spaltenwerten mit Tabellenwerten können jedoch keine Standardwerte zugewiesen werden, indem SQL_DEFAULT_PARAM in StrLen_or_IndPtr mit SQLBindParameter verwendet werden. Tabellenwertparameter als Ganzes können nicht auf einen Standardwert festgelegt werden, indem SQL_DEFAULT_PARAM in StrLen_or_IndPtr mit SQLBindParameter verwendet wird. 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 zuerst 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. Durch festlegen SQL_SOPT_SS_PARAM_FOCUS auf 0 wird die übliche Wirkung von SQLBindParameter, SQLSetDescRec und SQLSetDescField bei der Ausführung normaler Parameter auf oberster 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 unixODBC zwischen ANSI- und Unicode-Zeichenfolgen, je nach der genauen Funktion aufgerufen (SQLSetDescFieldA / SQLSetDescFieldW). Es ist erforderlich, entweder 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 Parameter mit Tabellenwert eine Pseudospalte ist, verweisen die Parameter für SQLBindParameter wie folgt auf unterschiedliche 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 optional für Aufrufe gespeicherter Prozeduren, und NULL kann angegeben werden, wenn sie nicht erforderlich ist. Es 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 Tabellenwert-Parametertypname für einen 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 verwendete Wert StrLen_or_IndPtr sollte entweder SQL_NTS oder die Zeichenfolgenlänge des Namens multipliziert mit der Größe (WCHAR) sein.
BufferLength SQL_DESC_OCTET_LENGTH in APD Die Länge des Typnamens des Tabellenwertparameters in Byte

Dies kann SQL_NTS werden, wenn der Typname null beendet ist, oder 0, wenn der Parametertypname mit Tabellenwert 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 folgende Aktionen 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. Binden Sie für jeden Parameter mit Tabellenwert mithilfe von SQLBindParameter-, SQLSetDescRec- oder SQLSetDescField-Aufrufen Tabellenwertparameterspalten.

    2. Ruft für jede Tabellenwertparameterspalte, die Standardwerte enthalten 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 erfolgen, bevor SQLExecute oder SQLExecDirect aufgerufen wird. Andernfalls wird SQL_ERROR zurückgegeben, und ein Diagnosedatensatz wird mit SQLSTATE=HY024 generiert und die Meldung "Ungültiger Attributwert, SQL_SOPT_SS_PARAM_FOCUS (muss zur Ausführungszeit null sein)."

  4. Legt fest, StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR auf SQL_DEFAULT_PARAM für einen Parameter mit Tabellenwert ohne Zeilen oder die Anzahl der Zeilen, die beim nächsten Aufruf von SQLExecute oder SQLExecDirect übertragen werden sollen, wenn der Parameter mit Tabellenwert Zeilen enthält. StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR können für einen Tabellenwertparameter nicht auf SQL_NULL_DATA festgelegt werden, da tabellenwertige Parameter nicht nullwertefähig sind (obwohl tabellenwertige Parameterspalten nullfähig sein 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 generiert und die Meldung "Ungültige Zeichenfolge oder Pufferlänge für Parameter <p>", wobei p die Parameternummer ist.

  5. Ruft SQLExecute oder SQLExecDirect auf.

    Spaltenwerte für eingabetabellenwertige Parameter 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 Daten-at-Execution-Parametern gibt SQLParamData nicht an, für welche Zeile des Arrays der Treiber Daten anfordert; der Antrag muss sich darum kümmern. Die Anwendung kann keine Annahmen über die Reihenfolge treffen, in der der Treiber Werte anfordert.

Variable Tabellenwertparameter-Zeilenbindung

Bei variabler Zeilenbindung 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 Spalten mit Tabellenwerten, wie in den Schritten 1 bis 3 des vorherigen Abschnitts "Zeilenbindung mit festem Tabellenwertparameter" beschrieben.

  2. Legt StrLen_or_IndPtr oder SQL_DESC_OCTET_LENGTH_PTR fest, damit tabellenwertige Parameter zur Ausführungszeit an SQL_DATA_AT_EXEC übergeben werden. Wenn keines festgelegt ist, wird der Parameter wie im vorherigen Abschnitt beschrieben verarbeitet.

  3. Ruft SQLExecute oder SQLExecDirect auf. Dies gibt SQL_NEED_DATA zurück, wenn SQL_PARAM_INPUT oder SQL_PARAM_INPUT_OUTPUT Parameter als Daten-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 einen 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 Daten-at-Execution-Parametern 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. Zum Senden von Tabellenwert-Parameterzeilendaten für Null-Parameter mit Tabellenwert, wenn der Parameter mit Tabellenwert keine Zeilen enthält, ruft eine Anwendung SQLPutData auf, wobei 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 geeignete Werte fest und füllt Datenpuffer für Spalten mit Tabellenwertparametern, die keine Daten bei ausführungsparametern sein sollen. 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. Ein beliebiger 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ählungszeichenelement 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 einem Str_Len_or_Ind Wert von 0 auf, und fahren Sie dann mit Schritt 3a oben fort.

  6. Ruft SQLParamData erneut auf. Wenn datenbasierte Ausführungsparameter zwischen den Tabellenwertparameterspalten vorhanden sind, werden diese durch den wert ValuePtrPtr , der von SQLParamData zurückgegeben wird, identifiziert. 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

ODBC-Parameter mit Tabellenwert