15

Ich habe zwei gespeicherte Prozedur einer mit sp_executesql geschrieben und andere haben nicht Sp_executesql beide richtig gleiche Ergebnisse ausgeführt werden, habe ich nicht bekommen, was der Unterschied zwischenGespeicherte Prozedur EXEC vs sp_executesql Unterschied?

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

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

Below Stored Procedure 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' 
+4

WHOA passieren !!! Hört auf, bereits SQL-Injektionen zu codieren Jedes Mal, wenn Sie sp_executesql aufrufen, lassen Sie möglicherweise jeden Joe Hacker im Internet in Ihren Server ein. – SecurityMatt

Antwort

12

Ihre Sp_executesql SQL sollte wahrscheinlich sein;

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

Dies ermöglicht es Ihnen Sp_executesql mit @eStatus als Parameter anstelle der Einbettung in die SQL zu nennen. Das wird den Vorteil haben, dass @eStatus beliebige Zeichen enthalten kann und es ordnungsgemäß von der Datenbank automatisch maskiert wird, wenn sie sicher sein muss.

Vergleichen Sie das mit dem SQL erforderlich für EXEC;

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

... wo ein char (39) in @Status eingebettet wird Ihre SQL ungültig und möglicherweise erstellen Sie eine SQL-Injection-Möglichkeit Gebrauch machen. Wenn zum Beispiel @Status auf O'Reilly gesetzt ist, wäre Ihr resultierender SQL;

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

Warum where-Klausel nicht mit ''' eingeschlossen ist? –

+0

@ user1095881 Wenn Sie @eStatus mit Anführungszeichen umschließen, wird nach dem _string_ '@eStatus' in der Datenbank gesucht. Wenn Sie einen nicht angegebenen @eStatus verwenden, wird _value_ verwendet. Wenn zum Beispiel @eStatus 'test' ist, würde ein 'INSERT INTO myTable VALUES (@eStatus)' den String 'test' einfügen, während 'INSERT INTO myTable VALUES ('@eStatus')' den String '@eStatus' einfügen würde ". –

+0

Ich denke, dass ein abschließendes '' 'im ersten Codebeispiel fehlt. – Sam

4

Mit sp_executesql, Sie müssen nicht Ihre Abfrage so bauen. Man könnte es so erklären:

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

Auf diese Weise, wenn Ihr @Status Wert von einem Benutzer kamen Sie @eStatus und müssen sich keine Sorgen über Flucht ' verwenden können. sp_executesql gibt Ihnen die Möglichkeit, Variablen in Ihre Abfrage in Form von Zeichenfolgen einzufügen, anstatt Verkettungen zu verwenden. Sie müssen sich also weniger Sorgen machen.

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

11

Neben der Nutzung gibt es einige wichtige Unterschiede:

  1. sp_executesql ermöglicht Aussagen parametriert werden daher sicherer Es ist als EXEC in Bezug auf SQL-Injection-

  2. sp_executesql können Nutzung zwischengespeicherter Abfragepläne. Die TSQL Zeichenfolge nur einmal gebaut, danach jedes Mal dieselbe Abfrage mit sp_executesql aufgerufen wird, ruft SQL Server die Abfrage-Plan aus dem Cache und verwendet es

  3. Temp Tabellen in EXEC erstellt nicht temporäre Tabelle Caching-Mechanismus verwenden können

+0

2. Unterschied ist die wichtigste ein imo (und hohe Upvoted Antworten nicht einmal erwähnen). +1 – sotn

+0

Vielen Dank für Ihre Erwähnung – FLICKER

1

Mit Exec Sie können keine Platzhalter in Ihrem T-SQL-Anweisung String haben.

Sp_executesql gibt Ihnen den Vorteil, einen Platzhalter mit und den Istwert bei Laufzeit

Verwandte Themen