jTDS +存储过程+ prepareSQL =嵌套级错误?

bar*_*ven 7 java sql-server stored-procedures jtds sql-server-2008

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

问题
jTDS驱动程序有时会(在应用程序的不同位置)回复错误:

超出最大存储过程,函数,触发器或视图嵌套级别(限制32).

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

问题

  1. 只使用存储过程来执行,当然在Java代码中使用Prepared Statements,对我们有多大的影响prepareSQL=3(或prepareSQL=0)?换句话说:在每个网站上我都会发现人们说"从不prepareSQL=0在生产环境中使用",那是否也适用于这种情况?

  2. 如果prepareSQL=0不是推荐的解决方案,安全问题等,我们应该寻找另一个驱动程序.jTDS在过去的两年里没有更新,微软有一个JDBC 4.0的驱动程序.我找不到jTDS和微软的JDBC 4.0驱动程序之间的任何基准或比较.使用Microsoft的2.0和3.0驱动程序,一般意见似乎是jTDS更快,更好,更高效.JDBC 4.0仍然如此,或者微软是否通过了它的竞争对手?

小智 2

当prepareSQL不等于0时,jTDS恰好添加一层嵌套。考虑以下程序:

CREATE PROCEDURE F @v int
AS
BEGIN
    select @v = @v - 1
    IF @v = 0 SELECT @v
    ELSE EXEC F @v
END
Run Code Online (Sandbox Code Playgroud)

以及使用它的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();
Run Code Online (Sandbox Code Playgroud)

如果将prepareSQL设置为0以外的值,它将失败并显示“超出最大存储过程、函数、触发器或视图嵌套级别(限制32)”。您需要找出为什么您的代码使用如此多的嵌套?通过prepareSQL = 0,您将阻止mssql使用stamements以及强制在每次执行时解析SQL的那些。如果语句执行时间比语句编译时间长得多,这不是一个大问题(例如,如果存储过程执行 10 秒,那么如果编译多花费 10 毫秒也不是问题)。更换驱动程序不会有帮助,因为你也会遇到同样的问题。