Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как да свържа променливи в SQL низове

Можете да постигнете това (ако разбирам какво се опитвате да направите) с помощта на динамичен SQL.

Номерът е, че трябва да създадете низ, съдържащ SQL израза. Това е така, защото името на таблицата трябва да бъде указано в действителния SQL текст, когато изпълнявате оператора. Препратките към таблици и колони не могат да бъдат предоставени като параметри, те трябва да се показват в SQL текста.

Така че можете да използвате нещо като този подход:

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

EXEC (@stmt)

Първо създаваме SQL оператор като низ. Като се даде @KeyValue на 'Foo', това ще създаде низ, съдържащ:

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

В този момент това е просто низ. Но можем да изпълним съдържанието на низа като динамичен SQL израз, използвайки EXECUTE (или EXEC на кратко).

Старата школа sp_executesql процедурата е алтернатива на EXEC, друг начин за изпълнение на dymamic SQL, който също ви позволява да предавате параметри, вместо да указвате всички стойности като литерали в текста на оператора.

ПОСЛЕДВАНЕ

EBarr посочва (правилно и важно), че този подход е податлив на SQL инжектиране.

Помислете какво би се случило, ако @KeyValue съдържаше низа:

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

Низът, който ще създадем като SQL оператор, ще бъде:

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

Когато ИЗПЪЛНЯВАМЕ този низ като SQL оператор:

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

И не може да се инжектира само DROP TABLE. Всеки SQL може да бъде инжектиран и може да е много по-фин и дори по-престъпен. (Първите атаки могат да бъдат опити за извличане на информация за таблици и колони, последвани от опити за извличане на данни (имейл адреси, номера на сметки и др.)

Един от начините за справяне с тази уязвимост е да се потвърди съдържанието на @KeyValue, да се каже, че трябва да съдържа само букви и цифри (напр. проверете за знаци извън тези диапазони, като използвате LIKE '%[^A-Za-z0-9]%' . Ако бъде открит незаконен знак, отхвърлете стойността и излезте, без да изпълнявате никакъв SQL.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Отстраняване на неизправности при блокиране в Sql Server 2008

  2. Разлика между база данни и схема

  3. Добавяне на колона между две други колони в SQL сървъра

  4. Връщане на стойност от оператор INSERT в SQL Server 2008

  5. Функция на SQL Server ROUND():За какво е и защо трябва да ви е грижа?