Verkettung von INT und VARCHAR in EXEC erzeugt keinen Konvertierungsfehler

8

Gegeben die folgende Tabelle:

%Vor%

Ich wollte eine dynamische SQL-Abfrage mit EXEC bei einem Val -Wert ausführen:

%Vor%

Dies wird ohne Fehler ausgeführt und liefert das korrekte Ergebnis.

Ich gehe davon aus, dass dies zu einem Fehler führen wird:

  

Konvertierung fehlgeschlagen beim Konvertieren des Varchar-Wertes 'SELECT * FROM #T   WHERE Val = 'zum Datentyp int.

Da @Val vom Datentyp INT ist und nach den Regeln von Datentyp Vorrang muss die Abfrage in EXEC in INT konvertiert werden.

Meine Frage ist, warum hat der Aufruf von EXEC keinen Konvertierungsfehler verursacht?

Anmerkungen:

- Ich weiß über sp_executesql . Ich frage auch nicht nach einer Alternative. Ich frage nur nach einer Erklärung, warum kein Fehler erzeugt wurde.

- Die Antwort auf diese Frage scheint meine Situation nicht zu erklären, da sich die Frage auf% co_de bezieht % bis VARCHAR Verkettung.

    
Felix Pamittan 16.06.2016, 07:29
quelle

3 Antworten

6

Laut MSDN / BOL lautet die vereinfachte Syntax für EXEC[UTE] statement:

%Vor%

Wenige Anmerkungen:

1) Nach dieser Zeile ( { @string_variable | [ N ] 'command_string [ ? ]' } [ **+** ...n ] können wir etwas wie EXEC (@var1 + @var2 + @var3) schreiben, aber laut letztem Absatz erwartet SQL Server, dass diese Variablen einen der folgenden string -Datentypen haben: char , varchar , nchar oder nvarchar .

2) Diese Syntax verweist auch nur auf string variables ( @string_variable | [ N ] 'command_string [ ? ]' } [ + ...n ). Ich glaube, das ist der Grund, warum EXEC ('SELECT * FROM #T WHERE Val = ' + 3); fehlschlägt: 3 ist keine Variable.

3) Ich nehme an, dass wenn eine dieser Variablen keinen der oben genannten Stringtypen hat, SQL Server eine implizite Konvertierung durchführt. Ich gehe davon aus, dass die Quellvariable von INT (zum Beispiel) in NVARCHAR konvertiert wird, weil sie die höchste Datentyp Vorrang zwischen diesen String-Typen.

4) Dies ist nicht der einzige Ort, an dem die Priorität des Datentyps nicht funktioniert. ISNULL(param1, param2) ist nur ein weiteres Beispiel. In diesem Fall wird param2 in den Datentyp param1 konvertiert.

    
Bogdan Sahlean 19.06.2016, 16:12
quelle
0

Eine implizite Konvertierung von int in Zeichenkettentypen ist erlaubt, mindestens so weit zurück wie SQL Server 2008.

Siehe auch: Datentypkonvertierung (Datenbankmodul)

Sie können die implizite Konvertierung nicht deaktivieren: Gibt es eine Möglichkeit, die implizite Typkonvertierung in SQL Server zu deaktivieren?

Bearbeiten: Ich schrieb ursprünglich

  

'SELECT * FROM #T WHERE Val = ' + @Val wird vor dem Aufruf von EXEC erstellt.

Ich bin mir da nicht so sicher. Ich vermute jetzt, dass das Argument zu EXEC an einen Teil der DB-Engine übergeben wird, der es auf eine andere Art analysiert als wir es gewohnt sind.

    
Andrew Morton 16.06.2016 07:59
quelle
0

Alles, was MSDN über die Verkettung in EXEC [UTE] erzählt, ist:

  

Die Verkettung wird im SQL Server-Parser logisch ausgeführt und tritt nie im Speicher auf.

Wir können also nicht viel darüber wissen, was SQL Server tief in sich trägt. Wir wissen nur, dass EXEC einen Ausdruck nicht als Argument akzeptiert, sondern eine Liste von Strings akzeptiert, die durch '+' begrenzt sind.

Wenn Sie sich die Syntax ansehen:

%Vor%

Es unterstützt direkt eine Anzahl von Strings oder Variablen, die durch ein '+' Zeichen getrennt sind. Daher übergeben Sie einen Ausdruck nicht wirklich an EXEC, und Sie umgehen daher den SQL Server-Ausdrucksparser.

    
gofr1 16.06.2016 08:32
quelle

Tags und Links