情况
我有一个使用jTDS连接到MSSQL 2008数据库的(Tomcat)Java Web应用程序。此Java应用程序使用用户输入执行其99%的MSSQL存储过程。

问题
jTDS驱动程序有时(在应用程序中的不同位置)答复并显示错误:



我们可以通过在jTDS连接字符串中添加prepareSQL=0来避免这种情况。然后该错误随处消失,但是对于prepareSQL的所有其他值,该错误仍然存​​在。我不知道jTDS添加了多少个存储过程嵌套级别,但是显然对于我们的应用程序来说太多了。

问题

  • 仅执行存储过程,当然使用Java代码中的Prepared Statements,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也不是问题)。更改驱动程序无济于事,因为您将遇到相同的问题。

    10-08 19:29