sql >> Databáze >  >> RDS >> Sqlserver

Jak zřetězit proměnné do řetězců SQL

Můžete toho dosáhnout (pokud rozumím tomu, co se snažíte udělat) pomocí dynamického SQL.

Trik je v tom, že musíte vytvořit řetězec obsahující příkaz SQL. Je to proto, že název tabulky musí být uveden ve skutečném textu SQL, když provádíte příkaz. Odkazy na tabulky a sloupce nelze zadat jako parametry, ty se musí objevit v textu SQL.

Takže můžete použít něco jako tento přístup:

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

EXEC (@stmt)

Nejprve vytvoříme SQL příkaz jako řetězec. Vzhledem k @KeyValue 'Foo' by to vytvořilo řetězec obsahující:

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

V tuto chvíli je to jen provázek. Ale můžeme spustit obsah řetězce jako dynamický SQL příkaz pomocí EXECUTE (nebo EXEC ve zkratce).

Stará škola sp_executesql procedura je alternativou k EXEC, což je další způsob spouštění dynamického SQL, který také umožňuje předávat parametry namísto zadávání všech hodnot jako literálů v textu příkazu.

NÁSLEDOVAT

EBarr poukazuje (správně a co je důležité), že tento přístup je náchylný k SQL Injection.

Zvažte, co by se stalo, kdyby @KeyValue obsahoval řetězec:

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

Řetězec, který bychom vytvořili jako příkaz SQL, by byl:

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

Když tento řetězec PROVEDEME jako příkaz SQL:

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

A není to jen DROP TABLE, který by se dal aplikovat injekčně. Bylo možné vložit jakýkoli SQL a mohlo by to být mnohem jemnější a ještě hanebnější. (První útoky mohou být pokusy o získání informací o tabulkách a sloupcích, následované pokusy o získání dat (e-mailové adresy, čísla účtů atd.)

Jedním ze způsobů, jak vyřešit tuto chybu zabezpečení, je ověřit obsah @KeyValue, řekněme, že by měl obsahovat pouze abecední a číselné znaky (např. zkontrolujte znaky, které nejsou v těchto rozsazích, pomocí LIKE '%[^A-Za-z0-9]%' . Pokud je nalezen neplatný znak, pak hodnotu odmítněte a ukončete bez provedení jakéhokoli SQL.



  1. SQL vrátí počet pracovních dnů mezi 2 předávanými daty

  2. Export CSV z Mysql

  3. 5 Výhody Microsoft Access, které musíte znát

  4. Je možné vrátit prázdný řádek ze serveru SQL?