7

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

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

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

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

问题

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

  2. 如果prepareSQL=0不是推荐的解决方案、安全问题等,我们也许应该寻找另一个驱动程序。jTDS 在过去 2 年没有更新,Microsoft 有 JDBC 4.0 的驱动程序。我找不到 jTDS 和 Microsoft 的 JDBC 4.0 驱动程序之间的任何基准或比较。对于 Microsoft 的 2.0 和 3.0 驱动程序,普遍的看法似乎是 jTDS 更快、更好、更高效。JDBC 4.0 仍然是这种情况,还是微软在这方面超过了它的竞争对手?

4

1 回答 1

2

when prepareSQL is not equal to 0 jTDS add exactly one level on nesting. Consider follow procedure:

CREATE PROCEDURE F @v int
AS
BEGIN
    select @v = @v - 1
    IF @v = 0 SELECT @v
    ELSE EXEC F @v
END

And java code that use it:

 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();

If you set prepareSQL to value other than 0 it will fail with "Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32)". You need to find why your code use so much nesting? By prepareSQL=0 you are preventing mssql to use stamements and those forcing to parse SQL on each executing. It is not a big problem if statement execution time is much more that statement complation time (E.G. if stored procedyre executes 10 secondse it is not a problem if compilation took 10ms more). Changing driver won't help because you will have same issues.

于 2013-02-27T06:37:39.617 回答