【问题标题】:Round bracket in string with JDBC prepared statement带有 JDBC 准备语句的字符串中的圆括号
【发布时间】:2013-01-26 15:15:24
【问题描述】:

这是我的 Java JDBC 代码(例如经过修改和简化):

ps = connection.prepareStatement("SELECT a,b,c FROM mytable WHERE category ~ ?");
ps.setString(1, "my/super/category/abc(def");
                                      ^
                                      |
    +---------------------------------+
    |
//this character is problem
result = ps.executeQuery();

由于字符串中有圆括号,它不起作用。

如何在准备好的语句中转义圆括号?

编辑:根据我的回答(见下文),我的问题是正确的。

【问题讨论】:

  • 这意味着没有真正的记录存在。您可以在数据库上执行实际查询并查看是否返回任何行吗?
  • @Subba 是的,我在控制台上测试 SQL(使用 PostgreSQL 和 PGAdmin3),圆括号需要转义:SELECT... category="my/super/category/abc\\(def " 并且它有效 - 将返回预期的记录。
  • 括号在 SQL 中不需要转义。只有单引号需要。并且字符串应该用单引号括起来,而不是双引号。
  • @LadislavDANKO:您肯定不需要需要“转义”圆括号:sqlfiddle.com/#!12/1703d/1
  • 我试过了,我看到了。完美运行:select f.* from mytable f where f.id = '12345('.

标签: java sql jdbc parameters prepared-statement


【解决方案1】:

我会回答自己 - 问题在“~”(波浪号)中。

经过一番阐述,有一个有趣的发现:

当SQL代码是这样的时候(见SQL代码中的“等号”):

ps = connection.prepareStatement("SELECT a,b,c FROM mytable WHERE category = ?");

不需要转义。但是当 SQL 代码是这样的时候(见 SQL 代码中的“波浪号”标记):

ps = connection.prepareStatement("SELECT a,b,c FROM mytable WHERE category ~ ?");

如果有特殊字符,则需要转义,在这种情况下为“(”或“)”:

ps.setString(1, "super/category/abc(def".replaceAll("\\(", "\\\\(")));

这是因为模式匹配:PostgreSQL Pattern Matching 因为带有波浪号的 JDBC 驱动程序不知道圆括号是普通字符(如我的情况)还是用于模式匹配的分组符号,将项目分组为一个逻辑项目。

【讨论】:

    【解决方案2】:

    您可以通过将圆括号放在单引号内来转义此处的圆括号。

    【讨论】:

      【解决方案3】:

      我认为问题是查询没有返回结果,因为它需要在括号前设置转义字符,可以通过

      ps.setString(1, "my/super/category/abc\\(def");
      

      SQL 语法允许在字符串中包含转义字符。在 Java 中,您无法转义字符串中的括号。

      【讨论】:

      • 如果您的 sql 使用标准等号,例如“select ... where blabla = ?”你这样做,不需要逃避。如果您的 sql 类似于“select ... where blabla ~ ?”你肯定需要这样做: ps.setString(1, "category/abc\(def".replaceAll("\(", "\\\("));
      • 绝对有理由在 JDBC 或 SQL 中转义括号。
      • @LadislavDANKO 您能否指定哪些 SQL 以及您的语句未编译的操作。
      • @a_horse_with_no_name 我不知道是什么原因,但这在 Java 中是不可能的。我所做的只是逃脱了转义字符以作为值传递。
      • 您不需要转义 ( 字符。在 Java 和 SQL 中都没有(事实上我认为它会产生错误的结果)。你的答案是完全错误的。
      猜你喜欢
      • 1970-01-01
      • 2013-06-25
      • 1970-01-01
      • 2015-12-09
      • 2014-12-18
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多