Verwendungen von ODBC-Tabellenwertparametern
In diesem Thema werden die wichtigsten Benutzerszenarien für die Verwendung von Tabellenwertparametern mit ODBC erläutert:
Tabellenwertparameter mit vollständig gebundenen mehrzeiligen Puffern (Senden von Daten als Tabellenwertparameter mit allen Werten im Arbeitsspeicher)
Tabellenwertparameter mit Zeilenstreaming (Senden von Daten als Tabellenwertparameter mithilfe von Data-at-Execution)
Abrufen von Tabellenwertparameter-Metadaten aus dem Systemkatalog
Abrufen von Tabellenwertparameter-Metadaten für eine vorbereitete Anweisung
Tabellenwertparameter mit vollständig gebundenen mehrzeiligen Puffern (Senden von Daten als Tabellenwertparameter mit allen Werten im Arbeitsspeicher)
Bei der Verwendung mit vollständig gebundenen mehrzeiligen Puffern sind alle Parameterwerte im Arbeitsspeicher verfügbar. Dies ist beispielsweise für eine OLTP-Transaktion typisch, bei der Tabellenwertparameter in eine einzeln gespeicherte Prozedur gepackt werden können. Ohne Tabellenwertparameter wären mehrere Serveraufrufe oder die dynamische Generierung eines komplexen Batches mit mehreren Anweisungen erforderlich.
Der Tabellenwertparameter selbst wird mithilfe von SQLBindParameter zusammen mit den anderen Parametern 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 Tabellenwertparameter ist SQL_SS_TABLE, ein neuer SQL Server-spezifischer Typ. Der C-Bindungstyp für SQL_SS_TABLE muss stets SQL_C_DEFAULT sein. Für den gebundenen Parameter des Tabellenwertparameters werden keine Daten übertragen. Dieser wird zur Übergabe von Tabellenmetadaten und zur Steuerung der Datenübergabe in die einzelnen Spalten des Tabellenwertparameters verwendet.
Die Länge des Tabellenwertparameters ist auf die Anzahl der an den Server gesendeten Zeilen festgelegt. Der ColumnSize-Parameter von SQLBindParameter für einen Tabellenwertparameter gibt die maximal zu versendende Zeilenanzahl an. Dies ist die Arraygröße der Spaltenpuffer. ParameterValuePtr ist der Parameterpuffer für einen Tabellenwertparameter in SQLBindParameter. ParameterValuePtr und die zugehörige BufferLength dienen zur Übergabe des Namens des Tabellenwertparameter-Typs, sofern erforderlich. Der Typname wird nicht für gespeicherte Prozeduraufrufe benötigt, er ist jedoch für SQL-Anweisungen erforderlich.
Wenn bei einem Aufruf von SQLBindParameter der Name des Tabellenwertparameter-Typs angegeben wird, muss dieser immer als Unicode-Wert angegeben werden, auch bei Anwendungen, die als ANSI-Anwendungen erstellt wurden. Wenn Sie den Namen eines Tabellenwertparameter-Typs mithilfe von SQLSetDescField angeben, können Sie ein mit der Art der Anwendung kompatibles Literal verwenden. Der ODBC-Treiber-Manager führt die eventuell erforderliche Unicode-Konvertierung aus.
Metadaten für Tabellenwertparameter und Tabellenwertparameter-Spalten können individuell und explizit mithilfe von SQLGetDescRec, SQLSetDescRec, SQLGetDescField und SQLSetDescField geändert werden. Das Überladen von SQLBindParameter ist jedoch in der Regel praktischer und erfordert in den meisten Fällen keinen expliziten Deskriptorzugriff. Dieser Ansatz stimmt mit der Definition von SQLBindParameter für andere Datentypen überein, jedoch weichen die betroffenen Deskriptorfelder bei einem Tabellenwertparameter geringfügig ab.
Manchmal verwendet eine Anwendung einen Tabellenwertparameter mit dynamischem SQL, und der Name des Tabellenwertparameters muss bereitgestellt werden. Wenn dies der Fall ist und der Tabellenwertparameter 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 vorliegen 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 ist in der Prozedur demo_fixed_table-valued parameter_binding in der Beispielanwendung auf CodePlex verfügbar; weitere Informationen finden Sie unter Beispiele für SQL Server Database Engine.
Tabellenwertparameter mit Zeilenstreaming (Senden von Daten als Tabellenwertparameter mithilfe von Data-at-Execution)
In diesem Szenario stellt die Anwendung dem Treiber Zeilen nach Anforderung bereit. Diese werden an den Server gestreamt. Hierdurch wird das Puffern aller Zeilen im Arbeitsspeicher vermieden. Dies ist für Masseneinfügungs-/Aktualisierungsszenarien repräsentativ. Tabellenwertparameter bieten eine Leistungsfähigkeit, die zwischen Parameterarrays und Massenkopieren liegt. Tabellenwertparameter sind ebenso einfach zu programmieren wie Parameterarrays, sie bieten jedoch eine größere Flexibilität auf dem Server.
Das Binden des Tabellenwertparameters und der zugehörigen Spalten erfolgt wie im vorherigen Abschnitt "Tabellenwertparameter mit vollständig gebundenen mehrzeiligen Puffern" beschrieben, der Längenindikator des Tabellenwertparameters selbst wird jedoch auf SQL_DATA_AT_EXEC festgelegt. Der Treiber antwortet auf SQLExecute oder SQLExecuteDirect auf die für Data-at-Execution-Parameter übliche Weise und gibt SQL_NEED_DATA zurück. Wenn der Treiber zur Aufnahme von Daten für einen Tabellenwertparameter bereit ist, gibt SQLParamData den Wert von ParameterValuePtr in SQLBindParameter zurück.
Für einen Tabellenwertparameter verwendet eine Anwendung SQLPutData, um die Verfügbarkeit von Daten für die einzelnen Spalten des Tabellenwertparameters anzugeben. Wenn SQLPutData für einen Tabellenwertparameter aufgerufen wird, muss DataPtr stets NULL und StrLen_or_Ind entweder 0 oder eine Zahl kleiner als oder gleich der Arraygröße sein, die für Tabellenwertparameter-Puffer festgelegt wurde (der ColumnSize-Parameter von SQLBindParameter). Der Wert 0 gibt an, dass keine weiteren Zeilen für den Tabellenwertparameter vorhanden sind, und der Treiber fährt mit der Verarbeitung des nächsten tatsächlichen Prozedurparameters fort. Wenn StrLen_or_Ind nicht 0 ist, verarbeitet der Treiber die einzelnen Spalten des Tabellenwertparameters auf die gleiche Weise wie gebundene Parameter von Nicht-Tabellenwertparametern: Jede Tabellenwertparameter-Spalte kann ihre tatsächliche Datenlänge, SQL_NULL_DATA oder Data-at-Execution über ihren Längen-/Indikatorpuffer angeben. Die Übergabe von Tabellenwertparameter-Spaltenwerten kann ganz normal über wiederholte Aufrufe von SQLPutData erfolgen, wenn ein Zeichen oder Binärwert stückweise übergeben werden muss.
Nachdem alle Tabellenwertparameter-Spalten verarbeitet wurden, kehrt der Treiber zum Tabellenwertparameter zurück, um weitere Tabellenwertparameter-Datenzeilen zu verarbeiten. Bei Data-at-Execution-Tabellenwertparametern führt der Treiber daher nicht den üblichen sequenziellen Scan gebundener Parameter durch. Ein gebundener Tabellenwertparameter wird abgerufen, bis SQLPutData mit StrLen_Or_IndPtr gleich 0 aufgerufen wird. Zu diesem Zeitpunkt überspringt der Treiber die Tabellenwertparameter-Spalten und geht zum nächsten tatsächlich gespeicherten Prozedurparameter über. Wenn SQLPutData einen Indikatorwert größer als bzw. gleich 1 übergibt, verarbeitet der Treiber Tabellenwertparameter-Spalten und -Zeilen sequenziell, bis er über die Werte für alle gebundenen Zeilen und Spalten verfügt. Anschließend kehrt der Treiber zum Tabellenwertparameter zurück. Zwischen dem Empfang des Tokens für den Tabellenwertparameter von SQLParamData und dem Aufruf von SQLPutData(hstmt, NULL, n) für einen Tabellenwertparameter muss die Anwendung einzelne Tabellenwertparameter-Spaltendaten und Indikatorpufferinhalte für die nächste Zeile bzw. die nächsten Zeilen festlegen, die an den Server übergeben werden.
Beispielcode für dieses Szenario ist in der Routine demo_variable_table-valued parameter_binding in der Beispielanwendung auf CodePlex verfügbar; weitere Informationen finden Sie unter Beispiele für SQL Server Database Engine.
Abrufen von Tabellenwertparameter-Metadaten aus dem Systemkatalog
Wenn eine Anwendung SQLProcedureColumns für eine Prozedur aufruft, die über Tabellenwertparameter verfügt, wird DATA_TYPE als SQL_SS_TABLE zurückgegeben, und der Name des Tabellentyps für den Tabellenwertparameter lautet TYPE_NAME. 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 gibt den Namen des Schemas zurück, 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 sowie nach allen Spalten, die von ODBC selbst benötigt werden.
Die neuen Spalten werden nicht nur für Tabellenwertparameter, sondern auch für Parameter des CLR-benutzerdefinierten Typs aufgefüllt. Die vorhandenen Schema- und Katalogspalten von Parametern des benutzerdefinierten Typs werden noch aufgefüllt, in Zukunft wird die Anwendungsentwicklung jedoch durch gemeinsame Schema- und Katalogspalten für Datentypen, die diese erfordern, erleichtert. (Beachten Sie, dass XML-Schemaauflistungen einige Unterschiede aufweisen und nicht in dieser Änderung enthalten sind.)
Eine Anwendung verwendet SQLTables, um die Namen der Tabellentypen auf dieselbe Art zu bestimmen wie für permanente Tabellen, Systemtabellen und Ansichten. Die Einführung eines neuen Tabellentyps − TABLE TYPE − ermöglicht es einer Anwendung, Tabellentypen zu identifizieren, die mit Tabellenwertparametern verbunden sind. Tabellentypen und reguläre Tabellen verwenden unterschiedliche Namespaces. Daher können Sie den gleichen Namen für einen Tabellentyp und eine tatsächliche Tabelle verwenden. Für diesen Fall 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 annehmen, den Tabellennamen als den Namen einer tatsächlichen Tabelle oder als den Namen eines Tabellentyps interpretieren sollen.
Eine Anwendung verwendet SQLColumns, um die Spalten für einen Tabellentyp auf die gleiche Art zu bestimmen wie für permanente Tabellen. Sie muss jedoch zunächst SQL_SOPT_SS_NAME_SCOPE festlegen, um anzugeben, dass sie Tabellentypen anstatt von tatsächlichen Tabellen verwendet. SQLPrimaryKeys kann auch mit Tabellentypen verwendet werden – ebenfalls mithilfe von SQL_SOPT_SS_NAME_SCOPE.
Beispielcode für dieses Szenario ist in der Routine demo_metadata_from_catalog_APIs in der Beispielanwendung auf CodePlex verfügbar; weitere Informationen finden Sie unter Beispiele für SQL Server Database Engine.
Abrufen von Tabellenwertparameter-Metadaten für eine vorbereitete 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 Tabellenwertparameter abzurufen. Die IPD-Felder SQL_CA_SS_TYPE_SCHEMA_NAME und SQL_CA_SS_TYPE_CATALOG_NAME werden zum Abrufen seines Katalogs bzw. Schemas verwendet.
Tabellentypdefinitionen und Tabellenwertparameter müssen sich in derselben Datenbank befinden. Wenn eine Anwendung beim Verwenden von Tabellenwertparametern SQL_CA_SS_TYPE_CATALOG_NAME festlegt, meldet SQLSetDescField einen Fehler.
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-benutzerdefinierte Typen.
Eine Anwendung verwendet ebenfalls SQLColumns, um Spaltenmetadaten für Tabellenwertparameter in diesem Szenario abzurufen, da SQLDescribeParam keine Metadaten für die Spalten einer Tabellenwertparameter-Spalte zurückgibt.
Beispielcode für diese Verwendungsfälle ist in der Routine demo_metadata_from_prepared_statement in der Beispielanwendung auf CodePlex verfügbar; weitere Informationen finden Sie unter Beispiele für SQL Server Database Engine.
Änderungsverlauf
Aktualisierter Inhalt |
---|
Aktualisierte Links zu Beispielen. |