Как экранировать символы в SQL: кавычки, обратные слеши и безопасные строки
В разработке приложений и написании запросов баз данных разработчики часто сталкиваются с необходимостью корректно обрамлять строковые значения. Если специальный символ внутри строки не экранировать, запрос может привести к синтаксической ошибке или стать уязвимым для SQL‑инъекции. В этой статье разбираем основные способы экранирования символов в SQL, показываем примеры для разных СУБД и даём советы, как писать безопасный код.
Что такое экранирование символов и зачем оно нужно
Экранирование — это способ обозначить, что специальный символ должен восприниматься как обычный текст. В SQL специальными считаются символы, которые используются как разделители строк (' и "), спецсимволы в операторе LIKE (% и _), а также обратная косая черта (\) в некоторых диалектах. Неправильное экранирование или двойное экранирование может привести к логическим ошибкам в запросах, а использование строк из непроверённых источников создаёт риск SQL‑инъекций. Документация и опыт разработчиков подчёркивают, что некорректное вложенное экранирование приводит к уязвимостям, и для работы с непроверенными данными следует использовать подготовленные выражения, чтобы исключить возможность SQL‑инъекции.
Как экранировать одинарные кавычки
В большинстве диалектов SQL строки заключаются в одинарные кавычки. Чтобы вставить апостроф внутри строки, его нужно удвоить. Такой подход называется doubling up и описан в справочниках по языкам программирования: язык SQL, как и Pascal, BASIC и Fortran, избегает конфликтов разделителей, удваивая кавычку внутри строкового литерала. Например:
-- Правильный способ экранирования апострофа
SELECT 'O''Brien' AS LastName;
-- Строка с кавычками внутри
SELECT 'Это не "ошибка", это строка';
O''Brien— корректная запись фамилии O’Brien.- Вторая строка показывает, что двойные кавычки внутри одинарных кавычек не требуют экранирования.
Совет: старайтесь использовать один стиль кавычек для строк (обычно одинарные) и экранируйте только нужные символы. Если нужно экранировать много строк, можно написать функцию, которая заменяет ' на '', например:
-- SQL Server
SELECT REPLACE(@input, '''', '''''');
Экранирование обратной косой черты и других специальных символов
Диалекты SQL по‑разному трактуют обратную косую черту (\).
- MySQL в режиме, когда параметр
NO_BACKSLASH_ESCAPESвыключен (режим по умолчанию в старых версиях), использует\для экранирования специальных символов:\'для апострофа,\"для кавычки,\\для самой косой черты. В современных версиях рекомендуется включатьNO_BACKSLASH_ESCAPESи использовать стандартное удваивание кавычек. - PostgreSQL поддерживает стандартное экранирование апострофа через двойные кавычки. Для обратной косой черты используется синтаксис
E'string'с escape‑последовательностями:E'c:\\temp'создаст путьc:\temp. - SQL Server не поддерживает обратную косую черту как символ экранирования для строк. Вместо этого используются функции
QUOTENAMEиREPLACE.
Пример для MySQL:
-- Экспорт данных с экранированием обратной косой черты
INSERT INTO files(path) VALUES('C:\\Data\\backup.sql');
Пример для PostgreSQL:
-- Использование escape‑литерала
INSERT INTO files(path) VALUES (E'C:\\Data\\backup.sql');
Спецсимволы в операторе LIKE
Операторы LIKE и ILIKE используют % (любой набор символов) и _ (один символ). Чтобы искать эти символы как текст, используйте слово ESCAPE и задайте символ экранирования:
-- Найти строки, содержащие символ подчёркивания
SELECT name
FROM users
WHERE name LIKE '%\_%' ESCAPE '\\';
-- Найти строки, содержащие процент
SELECT comment
FROM logs
WHERE comment LIKE '%\%%' ESCAPE '\\';
Здесь обратная косая черта перед % и _ указывает, что символ должен интерпретироваться буквально. Значение после ESCAPE определяет символ, которым мы экранируем шаблон.
Безопасные динамические запросы и защита от SQL‑инъекций
Экранирование символов важно, но для данных от пользователя этого недостаточно. Опыт показывает, что использование строк как кода может привести к уязвимостям, особенно в веб‑приложениях, и злоумышленники могут выполнить SQL‑инъекцию через недостатки экранирования. Лучший способ защититься — использовать подготовленные выражения (prepared statements) и привязку параметров. Суть подхода в том, что структура запроса компилируется отдельно, а значения подставляются как параметры, поэтому они не могут изменить логику SQL.
Пример на T‑SQL (SQL Server):
-- Использование параметров в хранимой процедуре
CREATE PROCEDURE dbo.GetUser
@UserName NVARCHAR(100)
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM dbo.Users WHERE UserName = @UserName;
END
Пример на C# с ADO.NET:
string query = "SELECT * FROM Users WHERE UserName = @name";
using (var cmd = new SqlCommand(query, connection))
{
cmd.Parameters.AddWithValue("@name", userInput);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
// обработка результата
}
}
}
Благодаря параметрам апострофы и другие специальные символы воспринимаются как данные, и риск SQL‑инъекции исчезает.
Экранирование идентификаторов: QUOTENAME и квадратные скобки
Помимо строковых литералов, иногда необходимо экранировать имена таблиц, столбцов или баз данных, например, если они содержат пробелы, спецсимволы или совпадают с ключевыми словами. В SQL Server для этого предусмотрена функция QUOTENAME:
-- Добавить квадратные скобки вокруг имени
SELECT QUOTENAME('My Database'); -- [My Database]
-- Использовать кавычки
SELECT QUOTENAME('Table Name', '"'); -- "Table Name"
Также имена можно заключать в квадратные скобки вручную: [My Table]. В стандарте SQL используются двойные кавычки: "Table". Для динамического SQL лучше всегда использовать QUOTENAME.
Таблица: способы экранирования в разных СУБД
| СУБД | Как экранировать апостроф | Другие особенности |
|---|---|---|
| SQL Server | Удвоить ' → '' | Функция QUOTENAME для идентификаторов; параметризованные запросы. |
| MySQL | 'O''Brien' либо \' (если не включён NO_BACKSLASH_ESCAPES) | Спецсимволы \n, \r, \0; рекомендуется удваивать кавычки и использовать подготовленные запросы. |
| PostgreSQL | 'O''Brien' | Возможен синтаксис E'' для escape‑последовательностей; standard_conforming_strings должен быть включён. |
| SQLite | 'It''s OK' | Обратная косая черта не имеет специального значения, поэтому для спецсимволов достаточно удвоить кавычку. |
Полезные функции для экранирования
- REPLACE(строка, что, на_что) — заменяет одну подстроку другой, удобно для удвоения кавычек.
- QUOTENAME(имя [, разделитель]) (SQL Server) — добавляет разделители вокруг идентификатора и экранирует внутренние закрывающие символы.
- STRING_ESCAPE(строка, тип) (SQL Server 2016+) — экранирует спецсимволы для JSON, XML и HTML.
- ESCAPE символ — используется в
LIKEдля указания символа экранирования.
Лучшие практики и рекомендации
- Используйте параметры вместо конкатенации. Экранируйте строковые литералы лишь для фиксированного SQL; для данных от пользователя используйте подготовленные выражения. Несоблюдение этого правила приводит к SQL‑инъекциям.
- Чётко определяйте диалект SQL. Разные СУБД по‑разному трактуют обратную косую черту и escape‑последовательности. Читайте документацию для вашей СУБД.
- Удваивайте кавычки. Самый универсальный способ экранирования апострофа — писать две одинарные кавычки подряд.
- Используйте специальные функции. В SQL Server есть
QUOTENAME, а в MySQL —QUOTE()для безопасного формирования литералов. - Документируйте код. Явно комментируйте места, где происходит экранирование, чтобы другим разработчикам было понятно, зачем это сделано.
Внутренние ссылки
- Как скриптом изменить владельца БД MS SQL — руководство по смене владельца базы.
- MS SQL: конвертация строки в число — разбор функций
CASTиCONVERT. - Скрипты для ускорения работы на проекте 1С — советы по оптимизации SQL-запросов в 1С.
Итоги
Корректное экранирование символов в SQL — важная часть работы разработчика. Апострофы экранируются путём удвоения, спецсимволы в шаблонах LIKE прячутся через ESCAPE, а обратная косая черта имеет особое значение только в некоторых диалектах. Однако простого экранирования недостаточно — для работы с пользовательскими данными используйте подготовленные выражения и привязку параметров, чтобы защитить систему от SQL‑инъекций. Зная эти правила и применяя их на практике, вы избежите ошибок в запросах и повысите безопасность ваших приложений.
+ There are no comments
Add yours