Java 不运行带参数的准备好的语句并且不抛出任何错误
Posted
技术标签:
【中文标题】Java 不运行带参数的准备好的语句并且不抛出任何错误【英文标题】:Java does not run prepared statement with parameter and not throwing any errors 【发布时间】:2016-06-23 08:25:58 【问题描述】:我正在尝试在我的 MSSQL 数据库的“视图”中执行如下所示的简单查询。试了2天没有成功。所以我转向SO。
PreparedStatement preparedStatement = connection.prepareStatement(
"SELECT * FROM Vw_Transactions WHERE Cust_No=? ");
preparedStatement.setString(1, "1234");
ResultSet resultSet = preparedStatement.executeQuery();
问题是我在查询后没有得到任何回复。甚至没有错误。即使等待了很长时间,例如3分钟。等待长达 5 分钟后,我得到了一些结果。但这没用。我很想知道为什么在我做一些愚蠢的事情之前,比如对查询进行半消毒和字符串连接参数,作为最后的手段。
有趣的观察:
当我将客户 ID 硬编码到 字符串并跳过准备好的语句。它带来的结果非常快,所以现在我确定不是数据加载导致缓慢。 如果我运行相同的查询 当我使用示例客户 ID 时,它在 Visual Studio 控制台中 直接 如果我选择不同的 VIEW,相同的查询 format 有效 来自数据库我能看到的最后一条日志是:
> SQLServerPreparedStatement:3: calling sp_prepexec: PreparedHandle:0, SQL:SELECT * FROM Vw_Transactions WHERE Cust_No=@P0
注意:我已经提到了this 问题,我的不是重复的场景。我已经确定我没有那些错误。
【问题讨论】:
什么是sql数据类型字段Cust_No
?
根据 Cust_No
的数据类型,您可能会强制 SQL Server 对所有客户编号进行整数到字符串的转换(假设 Cust_No 是数字)。这将对所有行执行,并且会忽略视图内 Cust_No 上设置的所有索引。那么……在比较查询速度时,你真的做了WHERE Cust_No = '1234'
吗?
@Jan 在 Visual Studio 中我可以看到 Data Type: char
。是的,我做了`WHERE Cust_No='1234'`来硬编码我的java类的String中的参数。结果很快。
如果您为 String 发送 nvarchar 参数然后转换为 char(单字节字符集),可能会发生同样的情况。请参阅 msdn.microsoft.com/en-us/library/ms378988(v=sql.110).aspx 并尝试在您的数据库连接 URL 中设置 ;sendStringParametersAsUnicode=false
耶!它有效,如果没有像你这样的人对我说,我永远不会知道它。太棒了!我感激不尽。您能否将其发布为答案以及更多链接,以帮助我了解您如何知道屏幕后面发生的这种转换。我会尽快接受。 thnx thnx thnx。
【参考方案1】:
根据Cust_No
的数据类型,sqljdbc 驱动程序可能会以意外格式发送字符串。
这将强制在 SQL Server 中进行数据转换,从而使该表/视图上的所有索引都无用。
由于您的 Cust_No
在 SQL Server 中属于 char
类型,因此在这种情况下这将是一个字符集转换。
正如http://msdn.microsoft.com/en-us/library/ms378988(v=sql.110).aspx 指出的那样,默认情况下,字符串参数以Unicode (=nvarchar
) 形式发送,导致您的查询对所有Cust_No
执行char
到nvarchar
的转换。
尝试将;sendStringParametersAsUnicode=false
添加到您的连接字符串中以禁用此功能。
【讨论】:
以上是关于Java 不运行带参数的准备好的语句并且不抛出任何错误的主要内容,如果未能解决你的问题,请参考以下文章
JDBC 超时不抛出 SQLTimeoutException