Вы действительно задали здесь два разных вопроса.
Ни один из них не имеет особого отношения к Rails, поэтому я собираюсь ответить на них в общем (также потому, что я не знаком с Ruby!).
Как использовать '?' предотвратить SQL Injection
SQL Injection происходит, когда вы используете значения, предоставленные вне вашей программы, - предоставленные пользователем значения - непосредственно в операциях SQL. Например, предположим, что у вас этот псевдо код:
sql="SELECT foo FROM bar WHERE name='"+name+"'"
где возможно name
был пользователем переменная, содержащая введенные данные. Однако, если name
содержит одиночную кавычку ('), то механизм SQL будет считать, что одинарная кавычка была окончанием значения и продолжить синтаксический анализ оставшейся части переменной в виде текста SQL.
Использование заполнителей (таких как??) Избегает этого, потому что значение внутри заполнителя не нужно указывать - все содержимое заполнителя рассматривается как часть значения, ни одно из них не будет анализироваться как SQL, независимо от встроенных кавычек.
Кстати, фактическая форма используемых заполнителей несколько зависит от используемого БД-механизма и/или клиентской инфраструктуры. Натурально, Postgresql uses the $1
, $2
, etc for placeholders. Многие рамки расширяют это, чтобы позволить '?' и другие синтаксисы заполнителя.
Почему "% # {термин}%" используется в противоположность только # {термин}
подписывает SQL ILIKE operator использует '%' в качестве подстановочных знаков. Выражение, как:
taste ILIKE '%apple%'
будет соответствовать «яблоко», «rottenApple», «яблочное» или любой другой строки, содержащей «яблоко» с использованием без учета регистра матч.
Обратите внимание, что знаки на «%» являются частью правого операнда к ILIKE, в кавычках, так что вы не использовать заполнители, как это:
Candy.where("taste ILIKE %?%", "#{term}")
Альтернативой будет:
Candy.where("taste ILIKE '%' || ? || '%'", "#{term}")
Это работает, потому что ||
является оператором конкатенации, поэтому он связывает буквальное значение %
со значением заполнителя, а затем конечное значение литерала %
.
Обнаружено это с помощью быстрого [Google] (https://www.google.com.au/#q=postgres+prevent+sql+injection+question+mark): http://stackoverflow.com/a/ 3727860/551093 –
Может быть, было бы проще понять таким образом? Candy.where ("вкус ILIKE%?%", Термин) – Typpex