быстрое и грязное экранирование строки SQL - PullRequest
3 голосов
/ 10 августа 2011

Я заканчиваю работу над классом QueryBuilder для веб-приложения с базой данных postgresql.Он использует PreparedStatement для всех запросов и защищен от внедрения SQL.

Однако я хотел «быстрый и грязный» способ представления QueryBuilder с его toString() методом, только для целей отладки.Метод соберет строку запроса, как обычно, передается в PreparedStatement, затем просто заменяет каждый ? в строке соответствующим значением в одинарных кавычках.toString() javadoc предупредит других разработчиков, что это небезопасное приближение, которое будет использоваться только для отладки и т. Д. И т. Д.

Я знаю, что значения должны иметь двойные кавычки, удваивающиеся (т. Е. O'Connell экранируется до O''Connell).Есть ли какие-то другие специальные символы, которые я должен забыть?Я искал похожие вопросы, но нашел только людей, которых ругают за использование PreparedStatement (что им следует, пусть показывается запись).

РЕДАКТИРОВАТЬ: не хочет использовать сторонний инструмент дляэта конкретная задача, я действительно просто хочу быстро и грязно здесь.Я все равно ценю ссылки - я могу рассмотреть их для других целей.

ПОСЛЕДНИЕ РЕДАКТИРОВАТЬ: спасибо всем за полезные ссылки.Я просто хочу добавить, что для тех, кто спотыкается здесь из Google, используйте , а не , используйте эти приемы для всего, что попадает в базу данных, используйте PreparedStatement.

Ответы [ 3 ]

5 голосов
/ 10 августа 2011

Для «быстрого и грязного» побега достаточно удвоить апострофы. Имейте в виду, что вопросительные знаки уже находятся внутри строковых литералов:

SELECT column FROM table WHERE column = 'A question?' or column = ?

Вы не хотите заменить первый знак вопроса. Также следует позаботиться об этих угловых случаях:

SELECT /* Is this a comment?? */ * FROM table
-- -- --  Another comment??
WHERE column = ?

В этом утверждении есть только одно значение связывания. Для менее быстрого и грязного решения вы можете использовать библиотеку, например jOOQ , для этой проблемы (отказ от ответственности: я работаю в компании, стоящей за jOOQ). Он подойдет для вас, в том числе для более неприятных типов данных:

DSLContext ctx = DSL.using(SQLDialect.POSTGRES);
Object[] bindValues = { 1, "a'bc", Date.valueOf("2012-09-24"), "xy".getBytes() };
String string = ctx.query(
  "SELECT 1 WHERE A = ? AND B = ? AND C = ? AND D = ?",
  bindValues).toString();

Выше будет отображаться

SELECT 1 
WHERE A = 1 
AND B = 'a''bc'
AND C = date '2012-09-24' 
AND D = E'\\170\\171::bytea
2 голосов
/ 10 августа 2011

Если вы не против использования сторонней библиотеки с открытым исходным кодом, то я бы сказал, взгляните на Apache Commons Lang's StringEscapeUtils.escapeSql (String str) .

РЕДАКТИРОВАТЬ: Я только что проверил источник .Он делает только замену одинарной кавычки (') на две одинарные кавычки (''), как вы делаете.

1 голос
/ 10 августа 2011

Может быть, вы можете взглянуть на escapeJava(String input) из Apache StringEscapeUtils .

public static final String escapeJava (String input)

Экранирует символы в строке, используя правила строки Java.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...