sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man sammanfogar variabler till SQL-strängar

Du kan åstadkomma detta (om jag förstår vad du försöker göra) med dynamisk SQL.

Tricket är att du måste skapa en sträng som innehåller SQL-satsen. Det beror på att tabellnamnet måste anges i den faktiska SQL-texten när du kör satsen. Tabellreferenserna och kolumnreferenserna kan inte anges som parametrar, de måste finnas i SQL-texten.

Så du kan använda något liknande detta tillvägagångssätt:

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

EXEC (@stmt)

Först skapar vi en SQL-sats som en sträng. Givet ett @KeyValue av 'Foo', skulle det skapa en sträng som innehåller:

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

Vid det här laget är det bara ett snöre. Men vi kan exekvera innehållet i strängen, som en dynamisk SQL-sats, med EXECUTE (eller EXEC för korta).

Den gamla skolans sp_executesql proceduren är ett alternativ till EXEC, ett annat sätt att exekvera dynamisk SQL, som också låter dig skicka parametrar, snarare än att ange alla värden som bokstavliga i texten i satsen.

UPPFÖLJNING

EBarr påpekar (korrekt och viktigt) att detta tillvägagångssätt är känsligt för SQL-injektion.

Tänk på vad som skulle hända om @KeyValue innehöll strängen:

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

Strängen vi skulle producera som en SQL-sats skulle vara:

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

När vi UTFÖR den strängen som en SQL-sats:

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

Och det är inte bara ett DROPTBORD som skulle kunna injiceras. Vilken SQL som helst kan injiceras, och den kan vara mycket mer subtil och ännu mer skändlig. (De första attackerna kan vara försök att hämta information om tabeller och kolumner, följt av försök att hämta data (e-postadresser, kontonummer, etc.)

Ett sätt att ta itu med denna sårbarhet är att validera innehållet i @KeyValue, säg att det bara ska innehålla alfabetiska och numeriska tecken (t.ex. kontrollera om det finns tecken som inte är i dessa intervall med LIKE '%[^A-Za-z0-9]%' . Om ett olagligt tecken hittas, avvisa värdet och avsluta utan att köra någon SQL.



  1. Basera databasmodeller i verkligheten:A Blogger's Challenge

  2. Jag vill ta ut resultatet från mysqls connection.query och spara det i global scope chain i nodejs

  3. GROUP BY i Postgres - ingen likhet för JSON-datatyp?

  4. Relationsdatabasschema för event sourcing