it-swarm.com.de

Gespeicherte Prozedur EXEC vs sp_executesql Unterschied?

Ich habe zwei gespeicherte Prozeduren geschrieben, eine mit sp_executesql und andere haben nicht sp_executesql beide führen richtig die gleichen Ergebnisse aus, ich habe nicht verstanden, was hier der Unterschied ist

EXEC (@SQL) vs EXEC sp_executesql @SQL, N '@ eStatus varchar (12)', @eStatus = @Status

und wie ist EXEC (@SQL) anfällig für SQL-Injection und sp_executesql @SQL ...... nicht?

Unten gespeicherte Prozedur ohne sp_executesql

ALTER proc USP_GetEmpByStatus
(
@Status varchar(12)
)
AS
BEGIN
DECLARE @TableName AS sysname = 'Employee'
Declare @Columns as sysname = '*'
DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + @TableName + ' where Status=' + char(39) + @Status + char(39)
print (@SQL)
EXEC (@SQL)
END

EXEC USP_GetEmpByStatus 'Active'

Unten gespeicherte Prozedur mit sp_executesql

create proc USP_GetEmpByStatusWithSpExcute
(
@Status varchar(12)
)
AS
BEGIN
DECLARE @TableName AS sysname = 'JProCo.dbo.Employee'
Declare @Columns as sysname = '*'
DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + @TableName + ' where Status=' + char(39) + @Status + char(39)
print @SQL
exec sp_executesql @SQL, N'@eStatus varchar(12)', @eStatus = @Status
END

EXEC USP_GetEmpByStatusWithSpExcute 'Active'
25
Registered User

Ihre sp_executesql SQL sollte wahrscheinlich sein;

DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + 
            @TableName + ' where [email protected]'

Auf diese Weise können Sie sp_executesql mit @eStatus als Parameter aufrufen, anstatt es in SQL einzubetten. Dies hat den Vorteil, dass @eStatus beliebige Zeichen enthalten kann und von der Datenbank automatisch maskiert wird, wenn dies aus Sicherheitsgründen erforderlich ist.

Vergleichen Sie dies mit der SQL, die für EXEC erforderlich ist.

DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + 
            @TableName + ' where Status=' + char(39) + @Status + char(39)

... wenn ein in @Status eingebettetes Zeichen (39) Ihre SQL ungültig macht und möglicherweise eine SQL-Injection-Möglichkeit erzeugt. Wenn zum Beispiel @Status auf O'Reilly Gesetzt ist, würde Ihre resultierende SQL sein;

select acol,bcol,ccol FROM myTable WHERE Status='O'Reilly'
19

Neben der Verwendung gibt es einige wichtige Unterschiede:

  1. sp_executesql Ermöglicht die Parametrisierung von Anweisungen. Daher ist es in Bezug auf die SQL-Injection sicherer als EXEC

  2. sp_executesql Kann zwischengespeicherte Abfragepläne nutzen. Die TSQL-Zeichenfolge wird nur einmal erstellt. Nach jedem Aufruf derselben Abfrage mit sp_executesql Ruft SQL Server den Abfrageplan aus dem Cache ab und verwendet ihn erneut

  3. Temporäre Tabellen, die in EXEC erstellt wurden, können den temporären Tabellen-Cache-Mechanismus nicht verwenden

19
FLICKER

Mit sp_executesql, Sie müssen Ihre Abfrage nicht so erstellen. Sie könnten es so erklären:

DECLARE @SQL as nvarchar(128) = 'select ' + @Columns + ' from ' + 
@TableName + ' where [email protected]'

Auf diese Weise, wenn Ihr @Status Wert stammt von einem Benutzer, den Sie verwenden können @eStatus und müssen sich keine Sorgen um die Flucht machen '. Mit sp_executesql können Sie Variablen in Zeichenfolgenform in Ihre Abfrage einfügen, anstatt Verkettung zu verwenden. Sie müssen sich also weniger Sorgen machen.

Die Spalten- und Tabellenvariablen sind immer noch dieselben, aber es ist weniger wahrscheinlich, dass sie direkt von einem Benutzer stammen.

4
JeffB

Mit Exec Sie können kein Platzhalter in Ihrer T-Sql-Anweisungszeichenfolge verwenden.

sp_executesql gibt Ihnen den Vorteil, einen Platzhalter zu haben und den tatsächlichen Wert bei Laufzeit zu übergeben

2
Mohammadreza