情况
我有一个使用jTDS连接到MSSQL 2008数据库的(Tomcat)Java Web应用程序。此Java应用程序使用用户输入执行其99%的MSSQL存储过程。
问题
jTDS驱动程序有时(在应用程序中的不同位置)答复并显示错误:
我们可以通过在jTDS连接字符串中添加prepareSQL=0
来避免这种情况。然后该错误随处消失,但是对于prepareSQL
的所有其他值,该错误仍然存在。我不知道jTDS添加了多少个存储过程嵌套级别,但是显然对于我们的应用程序来说太多了。
问题
prepareSQL=3
(或prepareSQL=0
)对我们有多大影响?换句话说:在每个网站上我都发现人们说“从不在生产环境中使用prepareSQL=0
”,这也适用于这种情况吗? prepareSQL=0
不是推荐的解决方案,安全问题等,我们可能应该寻找其他驱动程序。在过去的两年中,jTDS尚未更新,并且Microsoft具有JDBC 4.0的驱动程序。但是,我找不到jTDS与Microsoft的JDBC 4.0驱动程序之间的任何基准测试或比较。使用Microsoft的2.0和3.0驱动程序,人们普遍认为jTDS更快,更好,更高效。 JDBC 4.0还是这种情况,还是Microsoft在这方面超过了竞争对手? 最佳答案
当prepareSQL不等于0时,jTDS在嵌套上添加恰好一个级别。考虑遵循程序:
CREATE PROCEDURE F @v int
AS
BEGIN
select @v = @v - 1
IF @v = 0 SELECT @v
ELSE EXEC F @v
END
以及使用它的Java代码:
Connection connection = DriverManager.getConnection("jdbc:jtds:sqlserver://xxx.xxx.xxx.xxx:1433/xxx;prepareSQL=0");
PreparedStatement statement = connection.prepareStatement("EXEC F ?");
statement.setInt(1, 32);
statement.execute();
如果将prepareSQL设置为非0的值,它将失败,并且“超出最大存储过程,函数,触发器或 View 嵌套级别(限制32)”。您需要找到为什么您的代码使用大量嵌套的原因?通过prepareSQL = 0,您可以防止mssql使用stamements以及那些强制在每次执行时解析SQL的语句。如果语句执行时间比语句编译时间长很多,这不是什么大问题(例如,如果存储的过程执行10秒,则编译再花费10ms也不是问题)。更改驱动程序无济于事,因为您将遇到相同的问题。