Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

So verketten Sie Variablen zu SQL-Strings

Sie können dies (wenn ich verstehe, was Sie tun möchten) mit dynamischem SQL erreichen.

Der Trick besteht darin, dass Sie eine Zeichenfolge erstellen müssen, die die SQL-Anweisung enthält. Das liegt daran, dass der Tabellenname im eigentlichen SQL-Text angegeben werden muss, wenn Sie die Anweisung ausführen. Die Tabellenreferenzen und Spaltenreferenzen können nicht als Parameter übergeben werden, diese müssen im SQL-Text erscheinen.

Sie können also etwa diesen Ansatz verwenden:

SET @stmt = 'INSERT INTO @tmpTbl1 SELECT ' + @KeyValue 
    + ' AS fld1 FROM tbl' + @KeyValue

EXEC (@stmt)

Zuerst erstellen wir eine SQL-Anweisung als Zeichenfolge. Bei einem @KeyValue von 'Foo' würde dies eine Zeichenfolge erstellen, die Folgendes enthält:

'INSERT INTO @tmpTbl1 SELECT Foo AS fld1 FROM tblFoo'

An diesem Punkt ist es nur eine Zeichenfolge. Aber wir können den Inhalt des Strings als dynamische SQL-Anweisung mit EXECUTE ausführen (oder EXEC kurz).

Das altmodische sp_executesql Die Prozedur ist eine Alternative zu EXEC, einer anderen Möglichkeit, dynamisches SQL auszuführen, bei der Sie auch Parameter übergeben können, anstatt alle Werte als Literale im Text der Anweisung anzugeben.

NACHVERFOLGUNG

EBarr weist (richtig und wichtig) darauf hin, dass dieser Ansatz anfällig für SQL Injection ist.

Überlegen Sie, was passieren würde, wenn @KeyValue enthielt die Zeichenkette:

'1 AS foo; DROP TABLE students; -- '

Die Zeichenfolge, die wir als SQL-Anweisung erzeugen würden, wäre:

'INSERT INTO @tmpTbl1 SELECT 1 AS foo; DROP TABLE students; -- AS fld1 ...'

Wenn wir diesen String als SQL-Anweisung AUSFÜHREN:

INSERT INTO @tmpTbl1 SELECT 1 AS foo;
DROP TABLE students;
-- AS fld1 FROM tbl1 AS foo; DROP ...

Und es ist nicht nur eine DROP TABLE, die injiziert werden könnte. Es könnte jedes SQL eingeschleust werden, und es könnte viel subtiler und noch ruchloser sein. (Die ersten Angriffe können Versuche sein, Informationen über Tabellen und Spalten abzurufen, gefolgt von Versuchen, Daten (E-Mail-Adressen, Kontonummern usw.) abzurufen.

Eine Möglichkeit, diese Schwachstelle zu beheben, besteht darin, den Inhalt von @KeyValue zu validieren, sagen wir, er sollte nur alphabetische und numerische Zeichen enthalten (z ]%' . Wenn ein unzulässiges Zeichen gefunden wird, lehnen Sie den Wert ab und beenden Sie, ohne SQL auszuführen.