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.