【问题标题】:How do I handle special characters in a Java PrepareStatement?如何处理 Java PrepareStatement 中的特殊字符?
【发布时间】:2009-05-26 17:28:07
【问题描述】:

在以下 SQL 查询中使用PreparedStatement 类:

String query_descrip = "insert into timitemdescription (itemkey, languageid, longdesc, shortdesc) values (?, 1033, ?,?)";
PreparedStatement pstmt2 = con.prepareStatement(query_descrip); 
pstmt2.setInt(1, rs4);
pstmt2.setString(2, itemdescription);
pstmt2.setString(3, itemdescription.substring(0,39));
pstmt2.executeUpdate();       

我的商品描述中有时会出现撇号和单引号和双引号。例如,我最近发布的一个项目是“Planar 22”监视器。当然,字符串被误解了,认为描述值只是“Planar 22”。 处理字符串中特殊字符的最佳方法是什么?

我听说有些人正在使用正则表达式,但这些似乎是针对具体情况的。我正在研究的另一种方法是逐字符读取字符串数组。我希望有一种更有效、资源更少的方式来做到这一点。

更新 经过一些更广泛的测试后,我的代码中出现了更多问题。这也是一个 URL 编码问题。当jsp代码填充html表单时,它会尝试将描述字段移动到在线表单,它会在表单而不是查询中截断它。 jTDS 还纠正了接收特殊字符的问题。因为 jTDS 是一个 jar,它还有助于避免重新启动机器。我将奖励 jTDS 线程,因为那是我部分使用的。

提前致谢

【问题讨论】:

  • 您使用的是什么 JDBC 驱动程序和数据库?
  • 我正在使用用于 JDBC 和 SQL Server 2005 的 MS SQL Server 2000 驱动程序
  • 为什么我的问题被否决了?

标签: java string special-characters


【解决方案1】:

由于您使用的是 PreparedStatement,您根本不需要做任何事情,它会由 JDBC 驱动程序为您处理。您唯一需要注意的是非 ASCII 字符,特别是您必须确保 DB 表对可以处理您将使用的所有字符的文本列使用编码。但这是 SQL 问题,而不是 Java 问题。

【讨论】:

  • 当我将 itemdescription 传递给准备好的语句时,带有双引号的字符串不会被转义并解释为值终止符。您知道任何解决方法吗?
  • 您使用的是什么 SQL 服务器和驱动程序?如果它真的没有正确地转义字符串,那么它就有严重的缺陷(也可能在其他方面),我会考虑换一个。
  • 我正在使用用于 JDBC 和 SQL Server 2005 的 MS SQL Server 2000 驱动程序
  • 是否有更新版本的 JDBC 驱动程序?不转义引号将是一个绝对的阻止错误,使驱动程序完全一文不值。我简直不敢相信微软会发布如此明显损坏的版本。或者可能是您的代码有问题,尽管上面的示例看起来不错,但我不知道滥用 PreparedStatements 会导致此类问题的方法。让我有点怀疑的是,当值的其余部分无法解析时,被解释为值终止符的中间字符串应该会导致 SQLException。会这样吗?
  • 如果有,我将无法重新加载驱动程序的更新版本,因为其他程序正在使用它。它也在无法重启的服务器上运行。
【解决方案2】:

如果您将这些字符作为参数绑定到 PreparedStatement,则无需像您所做的那样专门处理这些字符。这是准备好的陈述方法的主要好处之一。

【讨论】:

    【解决方案3】:

    正如其他人所说,您不必做任何事情来处理特殊字符。您需要尝试不同的 JDBC 驱动程序。

    尝试使用jTDS driver,看看它是否对您的 PreparedStatement 有帮助。它是 SQL Server 的开源数据库驱动程序。我现在在工作中使用它,它就像一个冠军,实际上符合 JDBC 规范,不像 MS 驱动程序。

    【讨论】:

    • 您能否推荐任何示例代码或链接来实现准备好的语句的 jar 文件?
    • 您现在拥有的代码示例可以工作。唯一不同的是您用于创建连接的驱动程序 url。
    • 当我尝试运行 Class.forName("net.sourceforge.jtds.jdbc.Driver");在 try..catch 子句中,它一直告诉我“必须抓住或抛出”任何想法?
    • 没关系,当我只是从 sqlexception 更改异常时,它似乎正在工作
    【解决方案4】:

    我很确定问题不在于您发布的代码。帮助解决问题:

    1. 您是否尝试过在调试器中运行上面的代码 sn-p?在将“itemdescription”传递给数据库调用之前,它的值是多少?
    2. 您如何实际验证数据库中的值?这是更多的Java代码吗?还是你用 SQLCMD 或类似的东西来查看它?

    【讨论】:

      猜你喜欢
      • 2013-12-19
      • 1970-01-01
      • 1970-01-01
      • 2017-08-09
      • 2010-11-19
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多