Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Thema werden die primären Benutzerszenarien für die Verwendung von Tabellenwertparametern mit ODBC erläutert:
Table-Valued Parameter mit vollständig gebundenen Multirow-Puffern (Daten als TVP mit allen Werten im Arbeitsspeicher senden)
Table-Valued Parameter mit Zeilenstreaming (Daten als TVP mit Daten senden-At-Execution)
Abrufen Table-Valued Parametermetadaten aus dem Systemkatalog
Abrufen Table-Valued Parametermetadaten für eine prepared-Anweisung
Table-Valued Parameter mit vollständig gebundenen Multirow-Puffern (Daten als TVP mit allen Werten im Arbeitsspeicher senden)
Bei Verwendung mit vollständig gebundenen Multirow-Puffern sind alle Parameterwerte im Arbeitsspeicher verfügbar. Dies ist beispielsweise typisch für eine OLTP-Transaktion, in der Tabellenwertparameter in eine einzelne gespeicherte Prozedur verpackt werden können. Ohne Parameter mit Tabellenwerten würde dies entweder das dynamische Generieren eines komplexen Batches mit mehreren Anweisungen oder das Ausführen mehrerer Aufrufe an den Server umfassen.
Der Parameter mit Tabellenwert selbst wird zusammen mit den anderen Parametern mithilfe von SQLBindParameter gebunden. Nachdem alle Parameter gebunden wurden, legt die Anwendung das Parameterfokusattribut SQL_SOPT_SS_PARAM_FOCUS für jeden Tabellenwertparameter fest und ruft SQLBindParameter für die Spalten des Tabellenwertparameters auf.
Der Servertyp für einen Tabellenwertparameter ist ein neuer SQL Server-spezifischer Typ, SQL_SS_TABLE. Der Bindungs-C-Typ für SQL_SS_TABLE muss immer SQL_C_DEFAULT sein. Für den parametergebundenen Parameter mit Tabellenwert werden keine Daten übertragen; Sie wird verwendet, um Tabellenmetadaten zu übergeben und zu steuern, wie Daten in den Bestandteilspalten des Tabellenwertparameters übergeben werden.
Die Länge des Tabellenwertparameters wird auf die Anzahl der Zeilen festgelegt, die an den Server gesendet werden. Der Parameter ColumnSize von SQLBindParameter für einen Parameter mit Tabellenwert gibt die maximale Anzahl von Zeilen an, die gesendet werden können. Dies ist die Arraygröße der Spaltenpuffer. ParameterValuePtr ist der Parameterpuffer für einen Tabellenwertparameter in SQLBindParameter. ParameterValuePtr und der zugehörige BufferLength werden verwendet, um den Typnamen des Tabellenwertparameters bei Bedarf zu übergeben. Der Typname ist für Aufrufe gespeicherter Prozeduren nicht erforderlich, ist aber für SQL-Anweisungen erforderlich.
Wenn ein Tabellenwert-Parametertypname für einen Aufruf von SQLBindParameter angegeben wird, muss er immer als Unicode-Wert angegeben werden, auch in Anwendungen, die als ANSI-Anwendungen erstellt werden. Wenn Sie einen Tabellenwert-Parametertypnamen mithilfe von SQLSetDescField angeben, können Sie ein Literal verwenden, das der Art und Weise entspricht, wie die Anwendung erstellt wird. Der ODBC-Treiber-Manager führt die eventuell erforderliche Unicode-Konvertierung aus.
Metadaten für Tabellenwertparameter und Tabellenwertparameterspalten können einzeln und explizit mithilfe von SQLGetDescRec, SQLSetDescRec, SQLGetDescField, SQLGetDescField und SQLSetDescField bearbeitet werden. Das Überladen von SQLBindParameter ist jedoch in der Regel praktischer und erfordert in den meisten Fällen keinen expliziten Deskriptorzugriff. Dieser Ansatz entspricht der Definition von SQLBindParameter für andere Datentypen, mit der Ausnahme, dass für einen Tabellenwertparameter die betroffenen Deskriptorfelder geringfügig unterschiedlich sind.
Manchmal verwendet eine Anwendung einen Tabellenwertparameter mit dynamischem SQL, und der Typname des Tabellenwertparameters muss angegeben werden. Wenn dies der Fall ist und der Parameter mit Tabellenwert nicht im aktuellen Standardschema für die Verbindung definiert ist, müssen SQL_CA_SS_TYPE_CATALOG_NAME und SQL_CA_SS_TYPE_SCHEMA_NAME mithilfe von SQLSetDescField festgelegt werden. Da Tabellentypdefinitionen und Tabellenwertparameter in derselben Datenbank enthalten sein müssen, darf SQL_CA_SS_TYPE_CATALOG_NAME nicht festgelegt werden, wenn die Anwendung Tabellenwertparameter verwendet. Andernfalls meldet SQLSetDescField einen Fehler.
Beispielcode für dieses Szenario befindet sich in der Prozedur demo_fixed_TVP_binding unter "Use Table-Valued Parameters (ODBC)".
Table-Valued Parameter mit Zeilenstreaming (Daten als TVP mit Daten senden-At-Execution)
In diesem Szenario stellt die Anwendung Zeilen an den Treiber bereit, während sie sie anfordert und auf den Server gestreamt werden. Dadurch wird verhindert, dass alle Zeilen im Arbeitsspeicher gepuffert werden müssen. Dies ist repräsentativ für Masseneinfügungs-/Aktualisierungsszenarien. Tabellenwertparameter stellen einen Leistungspunkt zwischen Parameterarrays und Massenkopie bereit. Das heißt, Tabellenwertparameter sind ungefähr so einfach zu programmieren wie Parameterarrays, aber sie bieten eine größere Flexibilität auf dem Server.
Der Parameter mit Tabellenwert und die zugehörigen Spalten werden wie im vorherigen Abschnitt beschrieben gebunden, Table-Valued Parameter mit vollständig gebundenen Multirow-Puffern, aber der Längenindikator des Tabellenwertparameters selbst wird auf SQL_DATA_AT_EXEC festgelegt. Der Treiber antwortet auf SQLExecute oder SQLExecuteDirect in der üblichen Weise für Data-at-execution-Parameter, d. h. durch Zurückgeben von SQL_NEED_DATA. Wenn der Treiber bereit ist, Daten für einen Tabellenwertparameter zu akzeptieren, gibt SQLParamData den Wert von ParameterValuePtr in SQLBindParameter zurück.
Eine Anwendung verwendet SQLPutData für einen Tabellenwertparameter, um die Verfügbarkeit von Daten für Spalten mit Tabellenwertparametern anzugeben. Wenn SQLPutData für einen Tabellenwertparameter aufgerufen wird, muss DataPtr immer null sein, und StrLen_or_Ind muss entweder 0 oder eine Zahl kleiner oder gleich der Arraygröße sein, die für Tabellenwertparameterpuffer (der ColumnSize-Parameter von SQLBindParameter) angegeben ist. 0 gibt an, dass für den Parameter mit Tabellenwert keine weiteren Zeilen vorhanden sind, und der Treiber wird mit der Verarbeitung zum nächsten tatsächlichen Prozedurparameter fortgesetzt. Wenn StrLen_or_Ind nicht 0 ist, verarbeitet der Treiber die Tabellenwertparameter-Bestandteilspalten auf die gleiche Weise wie parametergebundene Parameter mit Nicht-Tabellenwert: Jede Parameterspalte mit Tabellenwert kann die tatsächliche Datenlänge, SQL_NULL_DATA angeben oder Daten zur Ausführung über den Längen-/Indikatorpuffer angeben. Spaltenwerte für Tabellenwerte können von wiederholten Aufrufen von SQLPutData wie gewohnt übergeben werden, wenn ein Zeichen oder binärer Wert in Teilen übergeben werden soll.
Wenn alle Tabellenwertparameterspalten verarbeitet wurden, kehrt der Treiber zum Tabellenwertparameter zurück, um weitere Zeilen mit Tabellenwertparameterdaten zu verarbeiten. Daher folgt der Treiber für parameter mit Daten bei der Ausführung von Tabellenwerten nicht der üblichen sequenziellen Überprüfung gebundener Parameter. Ein gebundener Tabellenwertparameter wird abgefragt, bis SQLPutData mit StrLen_Or_IndPtr gleich 0 aufgerufen wird, wobei der Treiber Tabellenwertparameterspalten überspringt und zum nächsten tatsächlich gespeicherten Prozedurparameter wechselt. Wenn SQLPutData einen Indikatorwert übergibt, der größer oder gleich 1 ist, verarbeitet der Treiber Tabellenwertparameterspalten und -zeilen sequenziell, bis er Werte für alle gebundenen Zeilen und Spalten enthält. Anschließend kehrt der Treiber zum Parameter mit Tabellenwert zurück. Zwischen dem Empfangen des Tokens für den Tabellenwertparameter aus SQLParamData und dem Aufrufen von SQLPutData(hstmt, NULL, n) für einen Tabellenwertparameter muss die Anwendung Tabellenwertparameter-Spaltendaten und Indikatorpufferinhalte für die nächste Zeile oder Zeile festlegen, die an den Server übergeben werden soll.
Beispielcode für dieses Szenario befindet sich in der Routine demo_variable_TVP_binding in "Verwenden von Table-Valued Parameters (ODBC)".
Abrufen Table-Valued Parametermetadaten aus dem Systemkatalog
Wenn eine Anwendung SQLProcedureColumns für eine Prozedur mit Parameterparametern mit Tabellenwert aufruft, wird DATA_TYPE als SQL_SS_TABLE zurückgegeben, und TYPE_NAME ist der Name des Tabellentyps für den Parameter mit Tabellenwert. Dem von SQLProcedureColumns zurückgegebenen Resultset werden zwei zusätzliche Spalten hinzugefügt: SS_TYPE_CATALOG_NAME gibt den Namen des Katalogs zurück, in dem der Tabellentyp des Tabellenwertparameters definiert ist, und SS_TYPE_SCHEMA_NAME den Namen des Schemas zurückgibt, in dem der Tabellentyp des Tabellenwertparameters definiert ist. In Übereinstimmung mit der ODBC-Spezifikation werden SS_TYPE_CATALOG_NAME und SS_TYPE_SCHEMA_NAME vor allen Treiberspezifischen Spalten angezeigt, die in früheren Versionen von SQL Server hinzugefügt wurden, und nach allen Spalten, die von ODBC selbst vorgeschrieben wurden.
Die neuen Spalten werden nicht nur für Parameter mit Tabellenwerten, sondern auch für benutzerdefinierte CLR-Typparameter aufgefüllt. Die vorhandenen Schema- und Katalogspalten von UDT-Parametern werden weiterhin aufgefüllt, aber mit allgemeinen Schema- und Katalogspalten für Datentypen, für die sie erforderlich sind, wird die Anwendungsentwicklung in Zukunft vereinfacht. (Beachten Sie, dass XML-Schemaauflistungen etwas anders sind und in dieser Änderung nicht enthalten sind.)
Eine Anwendung verwendet SQLTables, um die Namen von Tabellentypen auf die gleiche Weise zu bestimmen wie für persistente Tabellen, Systemtabellen und Ansichten. Ein neuer Tabellentyp, TABLE TYPE, wird eingeführt, um einer Anwendung die Identifizierung von Tabellentypen zu ermöglichen, die tabellenwertbezogenen Parametern zugeordnet sind. Tabellentypen und reguläre Tabellen verwenden unterschiedliche Namespaces. Dies bedeutet, dass Sie denselben Namen sowohl für einen Tabellentyp als auch für eine tatsächliche Tabelle verwenden können. Um dies zu behandeln, wurde ein neues Anweisungsattribut SQL_SOPT_SS_NAME_SCOPE eingeführt. Dieses Attribut gibt an, ob SQLTables und andere Katalogfunktionen, die einen Tabellennamen als Parameter verwenden, den Tabellennamen als Namen einer tatsächlichen Tabelle oder den Namen eines Tabellentyps interpretieren sollen.
Eine Anwendung verwendet SQLColumns, um die Spalten für einen Tabellentyp auf die gleiche Weise wie für persistente Tabellen zu bestimmen, muss jedoch zuerst SQL_SOPT_SS_NAME_SCOPE festlegen, um anzugeben, dass sie mit Tabellentypen und nicht mit tatsächlichen Tabellen arbeitet. SQLPrimaryKeys können auch mit Tabellentypen verwendet werden, wieder mit SQL_SOPT_SS_NAME_SCOPE.
Beispielcode für dieses Szenario befindet sich in der Routine demo_metadata_from_catalog_APIs in "Verwenden von Table-Valued Parameters (ODBC)".
Abrufen Table-Valued Parametermetadaten für eine prepared-Anweisung
In diesem Szenario verwendet eine Anwendung SQLNumParameters und SQLDescribeParam, um Metadaten für Tabellenwertparameter abzurufen.
Das IPD-Feld SQL_CA_SS_TYPE_NAME wird verwendet, um den Typnamen für den Parameter mit Tabellenwert abzurufen. Die IPD-Felder SQL_CA_SS_TYPE_SCHEMA_NAME und SQL_CA_SS_TYPE_CATALOG_NAME werden verwendet, um den Katalog bzw. das Schema abzurufen.
Tabellentypdefinitionen und Tabellenwertparameter müssen sich in derselben Datenbank befinden. SQLSetDescField meldet einen Fehler, wenn eine Anwendung bei Verwendung von Tabellenwertparametern SQL_CA_SS_TYPE_CATALOG_NAME festlegt.
SQL_CA_SS_TYPE_CATALOG_NAME und SQL_CA_SS_TYPE_SCHEMA_NAME können auch verwendet werden, um den Katalog und das Schema abzurufen, die mit Parametern des CLR-benutzerdefinierten Typs verbunden sind. SQL_CA_SS_TYPE_CATALOG_NAME und SQL_CA_SS_TYPE_SCHEMA_NAME sind Alternativen zu den vorhandenen typspezifischen Katalogschemaattributen für CLR-UDT-Typen.
Eine Anwendung verwendet SQLColumns zum Abrufen von Spaltenmetadaten für einen Tabellenwertparameter in diesem Szenario, da SQLDescribeParam keine Metadaten für die Spalten einer Tabellenwertparameterspalte zurückgibt.
Beispielcode für diesen Anwendungsfall befindet sich in der Routine demo_metadata_from_prepared_statement in "Use Table-Valued Parameters (ODBC)".