Was sind die Vor- und Nachteile der realen Welt bei der Ausführung eines dynamischen SQL-Befehls in einer gespeicherten Prozedur in SQL Server?
EXEC (@SQL)
gegen
EXEC SP_EXECUTESQL @SQL
?
Was sind die Vor- und Nachteile der realen Welt bei der Ausführung eines dynamischen SQL-Befehls in einer gespeicherten Prozedur in SQL Server?
EXEC (@SQL)
gegen
EXEC SP_EXECUTESQL @SQL
?
Antworten:
sp_executesql
fördert eher die Wiederverwendung von Abfrageplänen. Bei der Verwendung sp_executesql
werden Parameter in der aufrufenden Signatur explizit angegeben. Dieser ausgezeichnete Artikel beschreibt diesen Prozess .
Die oft zitierte Referenz für viele Aspekte von dynamischem SQL ist Erland Sommarskogs Muss: " Der Fluch und der Segen von dynamischem SQL ".
Das Besondere an SP_EXECUTESQL ist, dass Sie damit parametrisierte Abfragen erstellen können. Dies ist sehr gut, wenn Sie sich für die SQL-Injection interessieren.
In dem Artikel " Using sp_executesql" von Microsoft wird die Verwendung sp_executesql
anstelle der execute
Anweisung empfohlen .
Da diese gespeicherte Prozedur die Parametersubstitution unterstützt , ist sp_executesql vielseitiger als EXECUTE. und da sp_executesql Ausführungspläne generiert, die mit größerer Wahrscheinlichkeit von SQL Server wiederverwendet werden, ist sp_executesql effizienter als EXECUTE.
Also das Mitnehmen: Verwenden Sie keine execute
Anweisung . Verwenden Sie sp_executesql
.
sp_executesql
nicht ersetzt werden kann execute
. Vielleicht sollte ich den Punkt, den ich zu betonen versuche, wie folgt formulieren: Verwenden Sie sp_executesql
statt execute
wann immer möglich .
Ich würde heutzutage immer sp_executesql verwenden, alles was es wirklich ist, ist ein Wrapper für EXEC, der Parameter und Variablen behandelt.
Vergessen Sie jedoch nicht OPTION RECOMPILE, wenn Sie Abfragen in sehr großen Datenbanken optimieren, insbesondere wenn Sie Daten über mehr als eine Datenbank verteilt haben und eine Einschränkung verwenden, um Index-Scans einzuschränken.
Sofern Sie OPTION RECOMPILE nicht verwenden, versucht SQL Server, einen Ausführungsplan "Einheitsgröße" für Ihre Abfrage zu erstellen, und führt bei jeder Ausführung einen vollständigen Index-Scan durch.
Dies ist viel weniger effizient als eine Suche und bedeutet, dass möglicherweise ganze Indizes gescannt werden, die auf Bereiche beschränkt sind, die Sie nicht einmal abfragen: @
Führen Sie den Befehl aus
declare @sql varchar (100)
set @sql ='select * from #td1'
if (@IsMonday+@IsTuesday !='')
begin
set @sql= @sql+' where PickupDay in ('''+@IsMonday+''','''+@IsTuesday+''' )'
end
exec( @sql)
int
in dynamischem SQL sein. Beachten Sie, dass @sql als varchar
odernvarchar