java - 快速而肮脏的 SQL 字符串转义

标签 java sql postgresql escaping

我正在对带有 postgresql 数据库的 Web 应用程序的自制 QueryBuilder 类进行最后的润色。它对所有查询使用 PreparedStatement 并防止 SQL 注入(inject)。

但是我想要一种“快速而肮脏”的方式来表示 QueryBuilder 及其 toString() 方法,仅用于调试目的。该方法将按照通常传递到 PreparedStatement 的方式组装查询字符串,然后简单地将字符串中的每个 ? 替换为其相应的单引号值。 toString() javadoc 将警告其他开发人员这是一个不安全的近似值,仅用于调试等。

我知道值应该将它们的单引号加倍(即 O'Connell 转义为 O''Connell)。我忘记了还有其他特殊字符需要处理吗?我寻找了类似的问题,但只发现人们被责骂使用 PreparedStatement(他们应该这样做,让记录显示)。

编辑: 不想使用第三方工具来完成这项特定任务,我真的只想在这里快速而肮脏。尽管如此,我还是很欣赏这些链接 - 我可能会考虑将它们用于其他用途。

最后编辑:感谢大家的帮助。我只想补充一点,对于那些从 google 偶然发现这里的人,不要对任何访问数据库的东西使用这些技巧,使用PreparedStatement

最佳答案

对于“快速而肮脏”的转义,将撇号加倍就足够了。但是,请注意字符串文字中已经存在的问号:

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

您不想替换第一个问号。此外,应注意这些极端情况:

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

该语句中只有一个绑定(bind)值。对于不太快捷的解决方案,您可以使用像 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

关于java - 快速而肮脏的 SQL 字符串转义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7006586/

相关文章:

java - 来自 Java 的 SVN 分支信息

postgresql - 在 Postgresql 中选择位掩码

sql - Postgresql 计数+排序性能

PostgreSQL 在 RAISE NOTICE 上抛出错误 ||运算符(operator)

java - 使用递归找到迷宫中的最短路径?

java - Spring Boot 如何使用 HiddenHttpMethodFilter

java - 解析参数

php - 选择 ID 存在于另一列 MySQL 中的项目

mysql - 我需要优化以下sql查询

sql - oracle sql 选择语法与 GROUP BY 和 HAVING 子句