sp_describe_undeclared_parameters (Transact-SQL)
Gilt für: SQL Server Azure SQL-Datenbank Azure SQL Managed Instance Azure Synapse Analytics SQL Analytics-Endpunkt in Microsoft Fabric Warehouse in Microsoft Fabric
Gibt ein Resultset zurück, das Metadaten zu nicht deklarierten Parametern in einem Transact-SQL-Batch enthält. Berücksichtigt jeden im @tsql-Batch verwendeten, aber nicht in @params deklarierten Parameter. Ein Resultset wird zurückgegeben, das für jeden dieser Parameter eine Zeile mit den abgeleiteten Typinformationen für diesen Parameter enthält. Wenn der @tsql-Eingabebatch nur über Parameter verfügt, die in @params deklariert wurden, gibt die Prozedur ein leeres Resultset zurück.
Transact-SQL-Syntaxkonventionen
Syntax
sp_describe_undeclared_parameters
[ @tsql = ] 'Transact-SQL_batch'
[ , [ @params = ] N'@parameter_name data_type [ , ... n ]' ]
Hinweis
Um diese gespeicherte Prozedur in Azure Synapse Analytics in einem dedizierten SQL-Pool zu verwenden, legen Sie die Datenbankkompatibilitätsstufe auf 20
oder höher fest. Zum Deaktivieren ändern Sie die Datenbankkompatibilitätsstufe in 10
.
Argumente
[ @tsql = ] 'tsql'
Mindestens eine Transact-SQL-Anweisung. @tsql kann nvarchar(n) oder nvarchar(max)sein.
[ @params = ] N'@parameter_name data_type [ ,... n ]'
@params stellt eine Deklarationszeichenfolge für Parameter für den Transact-SQL-Batch bereit, ähnlich wie bei sp_executesql
der Funktionsweise. @params kann nvarchar(n) oder nvarchar(max)sein.
Eine Zeichenfolge, die die Definitionen aller Parameter enthält, die in @tsql eingebettet sind. Die Zeichenfolge muss eine Unicode-Konstante oder eine Unicode-Variable sein. Jede Parameterdefinition besteht aus einem Parameternamen und einem Datentyp. n ist ein Platzhalter für zusätzlicher Parameterdefinitionen. Wenn die Transact-SQL-Anweisung oder der Batch in der Anweisung keine Parameter enthält, ist @params nicht erforderlich. Der Standardwert für diesen Parameter ist NULL
.
Rückgabecodewerte
sp_describe_undeclared_parameters
gibt immer den Status null bei Erfolg zurück. Wenn die Prozedur einen Fehler auslöst und die Prozedur als RPC aufgerufen wird, wird der Rückgabestatus durch den Fehlertyp aufgefüllt, wie in der error_type
Spalte von sys.dm_exec_describe_first_result_set
. Wenn die Prozedur über Transact-SQL aufgerufen wird, lautet der Rückgabewert immer 0, auch bei Fehlern.
Resultset
sp_describe_undeclared_parameters
gibt das folgende Resultset zurück.
Spaltenname | Datentyp | BESCHREIBUNG |
---|---|---|
parameter_ordinal |
int | Enthält die Ordnungsposition des Parameters im Resultset. Die Position des ersten Parameters wird als 1 angegeben. Lässt keine NULL-Werte zu. |
name |
sysname | Enthält den Namen des Parameters. Lässt keine NULL-Werte zu. |
suggested_system_type_id |
int | Enthält den system_type_id Datentyp des Parameters gemäß der Angabe in sys.types .Bei CLR-Typen gibt diese Spalte den Wert 240 zurück, obwohl die system_type_name Spalte zurückgegeben NULL wird. Lässt keine NULL-Werte zu. |
suggested_system_type_name |
nvarchar(256) | Enthält den Namen des Datentyps. Enthält für den Datentyp des Parameters angegebene Argumente (z. B. Länge, Genauigkeit, Skala). Wenn der Datentyp ein benutzerdefinierter Aliastyp ist, wird der zugrunde liegende Systemtyp hier angegeben. Wenn es sich um einen benutzerdefinierten CLR-Datentyp handelt, NULL wird in dieser Spalte zurückgegeben. Wenn der Typ des Parameters nicht abgeleitet werden kann, NULL wird zurückgegeben. NULL-Werte sind zulässig. |
suggested_max_length |
smallint | Siehe sys.columns . für max_length spaltenbeschreibung. Lässt keine NULL-Werte zu. |
suggested_precision |
tinyint | Siehe sys.columns . enthält eine Beschreibung der Genauigkeitsspalte. Lässt keine NULL-Werte zu. |
suggested_scale |
tinyint | Siehe sys.columns . enthält eine Beschreibung der Skalierungsspalte. Lässt keine NULL-Werte zu. |
suggested_user_type_id |
int | Enthält für CLR- und Aliastypen den user_type_id Datentyp der Spalte, wie in sys.types angegeben. Andernfalls lautet NULL . NULL-Werte sind zulässig. |
suggested_user_type_database |
sysname | Enthält bei CLR- und Aliastypen den Namen der Datenbank, in der der Typ definiert wurde. Andernfalls lautet NULL . NULL-Werte sind zulässig. |
suggested_user_type_schema |
sysname | Enthält bei CLR- und Aliastypen den Namen des Schemas, in dem der Typ definiert wurde. Andernfalls lautet NULL . NULL-Werte sind zulässig. |
suggested_user_type_name |
sysname | Enthält bei CLR- und Aliastypen den Namen des Typs. Andernfalls lautet NULL . |
suggested_assembly_qualified_type_name |
nvarchar(4000) | Gibt bei CLR-Typen den Namen der Assembly und der Klasse zurück, die den Typ definiert. Andernfalls lautet NULL . NULL-Werte sind zulässig. |
suggested_xml_collection_id |
int | Enthält den xml_collection_id Datentyp des Parameters gemäß der Angabe in sys.columns . Diese Spalte gibt zurück NULL , wenn der zurückgegebene Typ keiner XML-Schemaauflistung zugeordnet ist. NULL-Werte sind zulässig. |
suggested_xml_collection_database |
sysname | Enthält die Datenbank, in der die XML-Schemaauflistung definiert ist, die diesem Typ zugeordnet wurde. Diese Spalte gibt zurück NULL , wenn der zurückgegebene Typ keiner XML-Schemaauflistung zugeordnet ist. NULL-Werte sind zulässig. |
suggested_xml_collection_schema |
sysname | Enthält das Schema, in dem die XML-Schemaauflistung definiert ist, die diesem Typ zugeordnet wurde. Diese Spalte gibt zurück NULL , wenn der zurückgegebene Typ keiner XML-Schemaauflistung zugeordnet ist. NULL-Werte sind zulässig. |
suggested_xml_collection_name |
sysname | Enthält den Namen der XML-Schemaauflistung, die diesem Typ zugeordnet wurde. Diese Spalte gibt zurück NULL , wenn der zurückgegebene Typ keiner XML-Schemaauflistung zugeordnet ist. NULL-Werte sind zulässig. |
suggested_is_xml_document |
bit | Gibt zurück 1 , wenn der zurückgegebene Typ XML ist und dieser Typ garantiert ein XML-Dokument ist. Andernfalls wird 0 zurückgegeben. Lässt keine NULL-Werte zu. |
suggested_is_case_sensitive |
bit | Gibt zurück 1 , wenn die Spalte einen Zeichenfolgentyp mit Groß-/Kleinschreibung aufweist und 0 wenn dies nicht der Fall ist. Lässt keine NULL-Werte zu. |
suggested_is_fixed_length_clr_type |
bit | Gibt zurück 1 , wenn die Spalte einen CLR-Typ mit fester Länge aufweist und 0 nicht. Lässt keine NULL-Werte zu. |
suggested_is_input |
bit | Gibt zurück 1 , wenn der Parameter an einer anderen Stelle als der linken Seite einer Zuordnung verwendet wird. Andernfalls wird 0 zurückgegeben. Lässt keine NULL-Werte zu. |
suggested_is_output |
bit | Gibt zurück 1 , wenn der Parameter auf der linken Seite einer Zuordnung verwendet wird oder an einen Ausgabeparameter einer gespeicherten Prozedur übergeben wird. Andernfalls wird 0 zurückgegeben. Lässt keine NULL-Werte zu. |
formal_parameter_name |
sysname | Wenn es sich bei dem Parameter um ein Argument für eine gespeicherte Prozedur oder eine benutzerdefinierte Funktion handelt, wird der Name des entsprechenden formalen Parameters zurückgegeben. Andernfalls wird NULL zurückgegeben. NULL-Werte sind zulässig. |
suggested_tds_type_id |
int | Nur zur internen Verwendung. Lässt keine NULL-Werte zu. |
suggested_tds_length |
int | Nur zur internen Verwendung. Lässt keine NULL-Werte zu. |
Hinweise
sp_describe_undeclared_parameters
gibt immer den Status null zurück.
Im häufigsten Anwendungsfall erhält eine Anwendung eine Transact-SQL-Anweisung, die möglicherweise Parameter enthält, die verarbeitet werden müssen. Ein Beispiel ist eine Benutzeroberfläche (z ODBCTest
. B. oder RowsetViewer
), auf der der Benutzer eine Abfrage mit ODBC-Parametersyntax bereitstellt. Die Anwendung muss die Anzahl der Parameter dynamisch ermitteln und bei jedem den Benutzer auffordern.
Ein weiteres Beispiel liegt vor, wenn eine Anwendung ohne Benutzereingabe eine Schleife in den Parametern ausführen und die Daten für diese von einem anderen Speicherort (z. B. einer Tabelle) abrufen muss. In diesem Fall muss die Anwendung nicht alle Parameterinformationen gleichzeitig übergeben. Stattdessen kann die Anwendung alle Parameterinformationen vom Anbieter und die Daten selbst aus der Tabelle abrufen. Die Verwendung von sp_describe_undeclared_parameters
Code ist allgemeiner und erfordert weniger Änderungen, wenn sich die Datenstruktur später ändert.
sp_describe_undeclared_parameters
gibt in einem der folgenden Fälle einen Fehler zurück.
Die Eingabe @tsql ist kein gültiger Transact-SQL-Batch. Die Gültigkeit wird durch Parsen und Analysieren des Transact-SQL-Batchs bestimmt. Alle Fehler, die während der Abfrageoptimierung oder während der Ausführung durch den Batch verursacht werden, werden nicht berücksichtigt, wenn ermittelt wird, ob der Transact-SQL-Batch gültig ist.
@params ist nicht
NULL
und enthält eine Zeichenfolge, die keine syntaktisch gültige Deklarationszeichenfolge für Parameter ist, oder wenn sie eine Zeichenfolge enthält, die einen Parameter mehr als einmal deklariert.Der Transact-SQL-Eingabebatch deklariert eine lokale Variable mit demselben Namen wie ein in @params deklarierter Parameter.
Die Anweisung verweist auf temporäre Tabellen.
Die Abfrage umfasst die Erstellung einer dauerhaften Tabelle, die dann abgefragt wird.
Wenn @tsql keine Parameter aufweist, außer parametern, die in @params deklariert sind, gibt die Prozedur ein leeres Resultset zurück.
Hinweis
Sie müssen die Variable als skalare Transact-SQL-Variable deklarieren oder ein Fehler angezeigt werden.
Parameterauswahlalgorithmus
Bei einer Abfrage mit nicht deklarierten Parametern erfolgt die Datentypableitung für nicht deklarierte Parameter in drei Schritten.
Schritt 1: Suchen der Datentypen der Unterausdrücke
Der erste Schritt beim Datentypabzug für eine Abfrage mit nicht deklarierten Parametern besteht darin, die Datentypen aller Unterausdrücke zu finden, deren Datentypen nicht von den nicht deklarierten Parametern abhängen. Der Typ kann für die folgenden Ausdrücke ermittelt werden:
- Spalten, Konstanten, Variablen und deklarierte Parameter.
- Ergebnisse eines Aufrufs einer benutzerdefinierten Funktion (User-Defined Function, UDF).
- Ein Ausdruck mit Datentypen, die nicht von den nicht deklarierten Parametern für alle Eingaben abhängen.
Sehen Sie sich dies beispielsweise für die Abfrage SELECT dbo.tbl(@p1) + c1 FROM t1 WHERE c2 = @p2 + 2
an. Die Ausdrücke und c2
weisen Datentypen dbo.tbl(@p1) + c1
und Ausdrücke @p1
auf und @p2 + 2
nicht.
Wenn nach diesem Schritt ein anderer Ausdruck als ein UDF-Aufruf über zwei Argumente ohne Datentypen verfügt, tritt bei der Typableitung ein Fehler auf. Beispielsweise führen alle folgenden Ausdrücke zu Fehlern:
SELECT * FROM t1 WHERE @p1 = @p2;
SELECT * FROM t1 WHERE c1 = @p1 + @p2;
SELECT * FROM t1 WHERE @p1 = SUBSTRING(@p2, 2, 3);
Im folgenden Beispiel wird kein Fehler erzeugt:
SELECT * FROM t1 WHERE @p1 = dbo.tbl(c1, @p2, @p3);
Schritt 2: Suchen innerster Ausdrücke
Bei einem bestimmten nicht deklarierten Parameter @p
findet der Typabzugsalgorithmus den innersten Ausdruck E(@p)
, der eines der folgenden Argumente enthält @p
und ist:
- Ein Argument für einen Vergleich oder ein Zuweisungsoperator.
- Ein Argument für eine benutzerdefinierte Funktion (einschließlich Tabellenwert-UDFs), Prozedur oder Methode.
- Ein Argument für eine
VALUES
Klausel einerINSERT
Anweisung. - Ein Argument für ein
CAST
oderCONVERT
.
Der Typabzugsalgorithmus findet einen Zieldatentyp TT(@p)
für E(@p)
. Für die vorherigen Beispiele sind die folgenden Zieldatentypen möglich:
- Der Datentyp der anderen Seite des Vergleichs oder der Zuweisung.
- Der deklarierte Datentyp des Parameters, an den dieses Argument übergeben wird.
- Der Datentyp der Spalte, in der dieser Wert eingefügt wird.
- Der Datentyp, in den die Anweisung umgewandelt oder konvertiert wird.
Sehen Sie sich dies beispielsweise für die Abfrage SELECT * FROM t WHERE @p1 = dbo.tbl(@p2 + c1)
an. Anschließend ist , TT(@p1)
ist der deklarierte Rückgabedatentyp von dbo.tbl
, und TT(@p2)
ist der deklarierte Parameter-Datentyp für dbo.tbl
.E(@p1) = @p1
E(@p2) = @p2 + c1
Wenn @p
nicht in einem Ausdruck enthalten ist, der am Anfang von Schritt 2 aufgeführt ist, bestimmt der Typabzugsalgorithmus, dass E(@p)
es sich um den größten skalaren Ausdruck handelt, der enthält @p
, und der Typabzugsalgorithmus berechnet keinen Zieldatentyp TT(@p)
für E(@p)
. Beispiel: Wenn die Abfrage dann E(@p) = @p + 2
ist SELECT @p + 2
, und es gibt keine TT(@p)
.
Schritt 3: Ableiten von Datentypen
E(@p)
Da der Typabzugsalgorithmus nun identifiziert wirdTT(@p)
, leitet der Typabzugsalgorithmus einen Datentyp @p
auf eine der folgenden beiden Arten ab:
Einfache Ableitung
Wenn
E(@p) = @p
undTT(@p)
vorhanden ist, d. h. wenn@p
es sich direkt um ein Argument für einen der ausdrücke handelt, die am Anfang von Schritt 2 aufgeführt sind, leitet der Typabzugsalgorithmus den Datentyp der@p
zu sein.TT(@p)
Zum Beispiel:SELECT * FROM t WHERE c1 = @p1 AND @p2 = dbo.tbl(@p3);
Der Datentyp für
@p1
,@p2
und@p3
ist der Datentyp vonc1
, der Rückgabedatentyp vondbo.tbl
, und der Parameter-Datentyp fürdbo.tbl
die jeweilige.Wenn es
@p
sich um ein Argument für ein<
,>
, oder<=
>=
einen Operator handelt – gelten keine einfachen Abzugsregeln. Der Typableitungsalgorithmus verwendet die allgemeinen, im nächsten Abschnitt erklärten Ableitungsregeln. Wennc1
es sich z. B. um eine Spalte vom Datentyp Char(30) handelt, sollten Sie die folgenden beiden Abfragen berücksichtigen:SELECT * FROM t WHERE c1 = @p; SELECT * FROM t WHERE c1 > @p;
Im ersten Fall leitet der Typabzugsalgorithmus Char(30) als Datentyp für
@p
die weiter oben in diesem Artikel beschriebenen Regeln ab. Im zweiten Fall leitet der Typableitungsalgorithmus anhand der im nächsten Abschnitt erläuterten allgemeinen Ableitungsregeln varchar(8000) ab.Allgemeine Ableitung
Wenn kein einfacher Abzug gilt, werden die folgenden Datentypen für nicht deklarierte Parameter berücksichtigt:
Ganzzahlige Datentypen (bit, tinyint, smallint, int, bigint)
Gelddatentypen (smallmoney, money)
Gleitkommadatentypen (float, real)
numeric(38, 19) – Andere numerische oder dezimale Datentypen werden nicht berücksichtigt.
varchar(8000), varchar(max), nvarchar(4000) und nvarchar(max). Andere Zeichenfolgendatentypen (z. B. text, char(8000) oder nvarchar(30)) werden nicht berücksichtigt.
varbinary(8000) und varbinary(max) – Andere binäre Datentypen werden nicht berücksichtigt (z . B. Bild, Binary(8000), varbinary(30), etc.).
Date, time(7), smalldatetime, datetime, datetime2(7), datetimeoffset(7) – Andere Datums- und Uhrzeittypen, z. B. "time(4)", werden nicht berücksichtigt.
sql_variant
xml
Systemdefinierte CLR-Typen (hierarchyid, geometry, geography)
Benutzerdefinierte CLR-Typen
Auswahlkriterien
Von den infrage kommenden Datentypen wird jeder Datentyp abgelehnt, durch den die Abfrage ungültig gemacht würde. Von den verbleibenden infrage kommenden Datentypen wählt der Typableitungsalgorithmus anhand der folgenden Regeln einen aus.
Der Datentyp, der die kleinste Anzahl impliziter Konvertierungen
E(@p)
erzeugt, wird ausgewählt. Wenn ein bestimmter Datentyp einen Datentyp erzeugt, derE(@p)
sich vonTT(@p)
dem unterscheidet, betrachtet der Typabzugsalgorithmus dies als zusätzliche implizite Konvertierung vom Datentyp inE(@p)
TT(@p)
.Zum Beispiel:
SELECT * FROM t WHERE Col_Int = Col_Int + @p;
In diesem Fall
E(@p)
istCol_Int + @p
undTT(@p)
ist int. int wird ausgewählt@p
, weil sie keine impliziten Konvertierungen erzeugt. Jeder andere ausgewählte Datentyp erzeugt mindestens eine implizite Konvertierung.Wenn mehrere Datentypen gleich wenige Konvertierungen erzeugen, wird der Datentyp mit dem höheren Rang verwendet. Zum Beispiel:
SELECT * FROM t WHERE Col_Int = Col_smallint + @p;
In diesem Fall erzeugen int und smallint genau eine Konvertierung. Jeder andere Datentyp erzeugt mehr als eine Konvertierung. Da int Vorrang vor smallint hat, wird int für
@p
. Weitere Informationen zur Rangfolge des Datentyps finden Sie unter "Rangfolge des Datentyps".Diese Regel gilt nur, wenn es eine implizite Konvertierung zwischen jedem Datentyp gibt, der gemäß Regel 1 und dem Datentyp mit der größten Rangfolge verknüpft ist. Wenn keine implizite Konvertierung vorhanden ist, schlägt der Datentypabzug mit einem Fehler fehl. Beispielsweise schlägt der Datentypabzug in der Abfrage
SELECT @p FROM t
fehl, da jeder Datentyp@p
gleich gut wäre. Beispielsweise gibt es keine implizite Konvertierung von Int in XML.Wenn zwei ähnliche Datentypen unter Regel 1 gleichwertig sind, z. B. varchar(8000) und varchar(max), wird der kleinere Datentyp (varchar(8000)) ausgewählt. Dasselbe Prinzip gilt für die Datentypen nvarchar und varbinary.
Für die Zwecke der Regel 1 bevorzugt der Typableitungsalgorithmus bestimmte Konvertierungen gegenüber anderen. Die Konvertierungen werden in der folgenden Reihenfolge bevorzugt (beste bis schlechteste):
- Konvertierung zwischen gleichem Basisdatentyp mit unterschiedlicher Länge.
- Konvertierung zwischen fester und variabler Version derselben Datentypen (z . B. Zeichen in Varchar).
- Konvertierung zwischen
NULL
und int. - Jede andere Konvertierung.
Für die Abfrage SELECT * FROM t WHERE [Col_varchar(30)] > @p
wird beispielsweise varchar(8000) ausgewählt, da die Konvertierung (a) am besten geeignet ist. Für die Abfrage SELECT * FROM t WHERE [Col_char(30)] > @p
wird ebenfalls varchar(8000) ausgewählt, da dieser Datentyp eine Konvertierung vom Typ (b) verursacht und eine andere Option (z. B. varchar(4000)) eine Konvertierung vom Typ (d) verursachen würde.
Als letztes Beispiel wird int eine Abfrage SELECT NULL + @p
ausgewählt@p
, da sie zu einer Typkonvertierung (c) führt.
Berechtigungen
Erfordert die Berechtigung zum Ausführen des @tsql Arguments.
Beispiele
Im folgenden Beispiel werden bestimmte Informationen zurückgegeben, z. B. der erwartete Datentyp für den nicht deklarierten @id
-Parameter und den nicht deklarierten @name
-Parameter.
EXEC sp_describe_undeclared_parameters @tsql =
N'SELECT object_id, name, type_desc
FROM sys.indexes
WHERE object_id = @id OR name = @name';
Wenn der @id
-Parameter als @params
-Verweis bereitgestellt wird, wird der @id
-Parameter im Resultset ausgelassen, und nur der @name
-Parameter wird beschrieben.
EXEC sp_describe_undeclared_parameters @tsql =
N'SELECT object_id, name, type_desc
FROM sys.indexes
WHERE object_id = @id OR NAME = @name',
@params = N'@id int';