情况
我有一个使用 jTDS 连接到 MSSQL 2008 数据库的 (Tomcat) Java Web 应用程序。此 Java 应用程序使用用户输入执行 99% 的 MSSQL 存储过程。
问题
jTDS 驱动程序有时(在应用程序的不同位置)回复错误:
Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).
我们可以通过将 prepareSQL=0
添加到 jTDS 连接字符串来避免这种情况。然后错误随处消失,但对于 prepareSQL
的所有其他值,错误仍然存在。我不知道 jTDS 添加了多少存储过程嵌套级别,但显然这对我们的应用程序来说太多了。
问题
只执行存储过程,当然在Java代码中使用Prepared Statements,
prepareSQL=3
(或prepareSQL=0
)效果如何对我们有什么换句话说:在每个网站上我都发现人们说“切勿在生产环境中使用prepareSQL=0
”,这是否也适用于这种情况?如果
prepareSQL=0
不是推荐的解决方案、安全问题等,我们也许应该寻找其他驱动程序。 jTDS 在过去 2 年没有更新,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 秒,如果编译多花费 10 毫秒,这不是问题)。更改驱动程序无济于事,因为您会遇到同样的问题。
关于java - jTDS + 存储过程 + prepareSQL = 嵌套级错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10426610/