gpt4 book ai didi

Java/Sql-server 参数绑定(bind)未按预期工作

转载 作者:行者123 更新时间:2023-12-02 03:46:04 25 4
gpt4 key购买 nike

我们注意到应用程序中有关绑定(bind)参数的奇怪行为。我们使用 Java 和 JDBC 来连接到 Sql Server 数据库。在表格单元格中,我们有值“μ”,并将其与绑定(bind)参数进行比较,该参数也设置为值“μ”。

现在,在像 "... where value != ?"这样的 sql 语句中,其中 'value' 是数据库中 'μ' 的值,而 ?绑定(bind)变量也设置为“μ”,我们注意到我们得到了一条记录,尽管我们期望“μ”等于“μ”。

我们用来填充绑定(bind)参数的方法是java.sql.PreparedStatement.setString(int, String)。

Some facts:

不同编码下μ的字符值为:

ASCII (ISO-8859-1) : 0xB5

UTF-8 : 0xC2B5

UTF-16 (= Java) : 0x00B5

现在我做了一些调查,看看数据库实际看到了哪些字节。因此我尝试了这样的sql语句:

select convert(VARBINARY(MAX), value), --  selects µ from database table
convert(VARBINARY(MAX), N'µ'), -- selects µ from literal
convert(VARBINARY(MAX), ?) -- selects µ from bind parameter
from ...

三个值的结果是:

B500
B500
C200B500 <-- Here is the problem!

因此,μ 在数据库中的内部表示以及 NVARCHAR 文字是 B500。

现在我们无法理解这里发生了什么。我们在 Java 变量中有“μ”的值(内部应该是 0x00B5)。当它作为绑定(bind)变量传递时,看起来好像它被转换为 UTF-8(这使得字节序列 0xC2B5),然后数据库将其视为两个字符,从中生成字符序列 C200B500。

让事情变得更加困惑:

(1) 在另一台具有不同数据库的计算机上,相同的代码可以按预期工作。这三行的结果是B500/B500/B500,因此绑定(bind)变量被转换为正确的B500。

(2) 在同一台机器上,相同的数据库但不同的程序(但使用相同的 jdbc 驱动程序库和相同的连接参数),这按预期工作,给出 B500 的结果/B500/B500。

一些额外的事实,也许它们很重要:数据库是Sql Server 2014Java 是 Java 7相关应用程序是在 Tomcat 7 中运行的 Web 应用程序。Jdbc库是sqljdbc 4.2

非常感谢任何解决此问题的帮助!

最佳答案

我现在找到了解决方案。它与 Sql Server 或绑定(bind)根本没有任何关系,而是......

Tomcat 7 默认情况下不以 UTF-8 模式运行(我不知道这一点)。我们正在讨论的 µ 来自另一个通过 Web 服务调用提供此值的应用程序。但是,应用程序默认使用 UTF-8。因此,它发送的是 UTF-8 µ,但 Web 服务并不期望 UTF-8,并认为这将是两个字符,并像这样处理它们,用 0xC2 和 0xB5 的字符填充内部 String 变量(即,对于 Sql Server,C200B500)。

关于Java/Sql-server 参数绑定(bind)未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56807450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com