Подтвердить что ты не робот

Как я могу работать с кавычками в SQL?

У меня есть база данных с именами в ней, такими как John Doe и т.д. К сожалению, некоторые из этих имен содержат цитаты типа Keiran O'Keefe. Теперь, когда я пытаюсь найти такие имена, выполните следующие действия:

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' 

I (понятно) получить сообщение об ошибке.

Как предотвратить эту ошибку. Я использую Oracle и PLSQL.

4b9b3361

Ответ 1

Эквивалентный символ равен ', поэтому вам нужно будет заменить цитату двумя кавычками.

Например,

SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe'

становится

SELECT * FROM PEOPLE WHERE SURNAME='O''Keefe'

Тем не менее, это, вероятно, неправильно сделать это самостоятельно. У вашего языка может быть функция, позволяющая избежать строк для использования в SQL, но еще лучше использовать параметры. Обычно это работает следующим образом.

Ваша команда SQL будет:

SELECT * FROM PEOPLE WHERE SURNAME=?

Затем, когда вы его выполняете, вы вводите параметр "O'Keefe" в качестве параметра.

Поскольку SQL анализируется до того, как значение параметра установлено, нет никакого способа изменить значение параметра в структуре SQL (и это даже немного быстрее, если вы хотите несколько раз запускать один и тот же оператор с разными параметрами).

Я также должен отметить, что, хотя ваш пример просто вызывает ошибку, вы открываете себя перед множеством других проблем, не избегая соответствующих строк. См. http://en.wikipedia.org/wiki/SQL_injection для хорошей отправной точки или следующей классической xkcd комический.

alt text

Ответ 2

Решение Oracle 10

SELECT * FROM PEOPLE WHERE SURNAME=q'{O'Keefe}'

Ответ 3

Я полагаю, что хороший вопрос - какой язык вы используете?
В PHP вы бы сделали: SELECT * FROM PEOPLE WHERE SURNAME = 'mysql_escape_string (O'Keefe)'
Но так как вы не указали язык, я предлагаю вам взглянуть на функцию escape-последовательности mysql или иначе на вашем языке.

Ответ 4

Параметризированные запросы - ваш друг, как это предлагает Мэтт.

Command = SELECT * FROM PEOPLE WHERE SURNAME=?

Они защитят вас от головных болей, связанных с

  • Строки с кавычками
  • Запрос с использованием дат
  • SQL Injection

Ответ 5

Использование параметризованного SQL имеет другие преимущества, это уменьшает накладные расходы процессора (а также другие ресурсы) в Oracle за счет сокращения объема работы Oracle, необходимого для анализа оператора. Если вы не используете параметры (мы называем их связующими переменными в Oracle), то "выберите * из foo, где bar = 'cat'" и "select * from foo, где bar = 'dog'" рассматриваются как отдельные инструкции, выберите * из foo, где bar =: b1 "- это тот же оператор, что означает такие вещи, как синтаксис, достоверность объектов, на которые ссылаются и т.д.... не нужно снова проверять. Бывают случайные проблемы, возникающие при использовании переменных связывания, которые обычно проявляются в том, что они не получают наиболее эффективный план выполнения SQL, но для этого существуют обходные пути, и эти проблемы действительно зависят от предикатов, которые вы используете, индексирования и искажения данных.

Ответ 6

Входная фильтрация обычно выполняется на уровне языка, а не в слоях базы данных.
php и .NET имеют свои соответствующие библиотеки для экранирования операторов sql. Проверьте свой язык, см. Waht.
Если ваши данные являются надежными, вы можете просто заменить строку, чтобы добавить еще один "infront of", чтобы избежать ее. Обычно этого достаточно, если нет никаких опасностей, что ввод вреден.

Ответ 7

Чтобы заключить сделки, если вы используете Zend Framework, здесь приведен код

$db = Zend_Db_Table_Abstract::getDefaultAdapter();

$db->quoteInto('your_query_here = ?','your_value_here');

например:

//SELECT * FROM PEOPLE WHERE SURNAME='O'Keefe' will become
SELECT * FROM PEOPLE WHERE SURNAME='\'O\'Keefe\''