Як? Параметри та оператор LIKE SQL


80

Я пишу пошукову функцію і продумав цей запит, використовуючи параметри для запобігання або, принаймні, обмеження атак введення SQL. Однак, коли я запускаю його через свою програму, це нічого не повертає:

SELECT * FROM compliance_corner WHERE (body LIKE '%@query%') OR (title LIKE '%@query%')

Чи можна використовувати параметри так? або вони дійсні лише у такому випадку, як:

SELECT * FROM compliance_corner WHERE body LIKE '%<string>%'(де <string>знаходиться об’єкт пошуку).

EDIT: Я будую цю функцію за допомогою VB.NET, чи це впливає на синтаксис, який ви внесли?

Крім того, я запустив це твердження в SQL Server: SELECT * FROM compliance_corner WHERE (body LIKE '%max%') OR (title LIKE% max% ') `і воно повертає результати.

Відповіді:


78

Ваш візуальний базовий код виглядатиме приблизно так:

Dim cmd as New SqlCommand("SELECT * FROM compliance_corner WHERE (body LIKE '%' + @query + '%') OR (title LIKE '%' + @query + '%')")

cmd.Parameters.Add("@query", searchString)

3
Як зазначив Адам у своїй відповіді, це не захищає від ін'єкції SQL. Запит повинен бути параметризований.
DOK

6
Не могли б ви навести приклад, коли це не перешкоджає введенню SQL? З мого тестування це працює нормально
Джон

27
Він не відкритий для SQLін’єкцій, лише LIKEін’єкція Це означає, що користувач може вводити спеціальні символи, такі як % ^і _які LIKEбудуть інтерпретуватися спеціально. Це означає, що користувач може не отримати того, що очікує від певних пошукових запитів. Як приклад, пошук 'less than 1% fat'може повернути результат 'less than 1% of doctors recommend this - it's full of fat!'.
Алекс Хамфрі,

1
Я погоджуюсь, що подібне підпадає під дію "Лайк-ін'єкції", і що шкода полягає лише в тому, що користувач не отримує того, що очікує. Санітарна обробка запитів повинна виконуватися постійно, навіть якщо параметризовані. Покладання лише на цей захист не є точно надійним.
Ентоні Мейсон,

1
Я також рекомендую зробити це searchString.Replace("[","[[]").Replace("%","[%]").Replace("_","[_]"), що призведе до введення типу LIKE (якщо ви не використовуєте клавішу Escape).
8DX

114

Ну, я б пішов із:

 Dim cmd as New SqlCommand(
 "SELECT * FROM compliance_corner"_
  + " WHERE (body LIKE @query )"_ 
  + " OR (title LIKE @query)")

 cmd.Parameters.Add("@query", "%" +searchString +"%")

Це правильно, прийнята відповідь, надана Джоном, має неправильний синтаксис!
Адам

3
Я не впевнений, наскільки його синтаксис неправильний, його рішення спрацювало чудово. У мене є функція, яка створює та повертає оператор SQL для використання в таблиці даних чи будь-якому іншому.
Андерс,

1
Додаткова примітка: Синтаксис для C # з використанням MySQLDataAdapter = da = new MySQLDataAdapter ("SELECT * FROM tableA WHERE fieldA = @fieldA"); da.SelectCommand.Parameters.AddWithValue ("@ fieldA", "%" + someValue + "%");
Джон М

3
Інша відповідь (від Джона) теж працює, але насправді є вразливою до подібних ін’єкцій, які МОЖУТЬ дати дивні результати, залежно від призначення вашої галузі.
Стівен Лемменс,

1
Не повинно бути , cmd.Parameters.Addстає cmdLoad.Parameters.AddWithValueабо є якісь - або проблеми? Я розумію, що відповідь Джеймса - з 2008 року :)
WTFZane

26

ви повинні зробити:

LIKE '%' + @param + '%'


відмінне рішення - дасть йому більше +1, якщо це можливо! Подяка
BM

2

Можливо, вам доведеться об'єднати знаки% з вашим параметром, наприклад:

ПОДОБАЄТЬСЯ '%' || @query || '%'

Редагувати: Насправді це може взагалі не мати сенсу. Думаю, я неправильно зрозумів вашу проблему.


1

Іноді символ, який використовується як заповнювач %, не однаковий, якщо ви виконуєте запит із VB, як коли ви виконуєте його з MS SQL / Access. Спробуйте змінити символ заповнювача з %на *. Це може спрацювати.
Однак, якщо ви налагоджуєте і хочете скопіювати свій рядок SQL безпосередньо в MS SQL або Access, щоб перевірити його, можливо, вам доведеться змінити символ назад на %MS SQL або Access, щоб фактично повернути значення.

Сподіваюся, це допомагає


Я точно не знаю на 2012 рік, але цей% проти * специфічний для двигунів ADO проти DAO. Якщо ви використовуєте DAO, або Current () у програмі Access, підстановка має значення *; якщо використовується ADO з будь-якого коду, включаючи VBA всередині Access, підстановка складає%.
Марсело Скофано Дініз,

1

спробуйте також цим способом

Dim cmd as New SqlCommand("SELECT * FROM compliance_corner WHERE (body LIKE CONCAT('%',@query,'%')  OR  title LIKE CONCAT('%',@query,'%') )")
cmd.Parameters.Add("@query", searchString)
cmd.ExecuteNonQuery()

Використовується Concat замість +

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.