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

标签 java sql-server sql-server-2008 stored-procedures jtds

情况
我有一个使用 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 添加了多少存储过程嵌套级别,但显然这对我们的应用程序来说太多了。

问题

  1. 只执行存储过程,当然在Java代码中使用Prepared Statements,prepareSQL=3(或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 是否仍然如此,或者 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/

相关文章:

java - 每次线程执行它的运行时获取一个值/返回一些东西

sql-server - SQL Server 2008 中的 Do while 循环

sql-server - SQL Server 复制触发器

sql - 如何查看 SQL Server 中 varchar 或 char 字段中允许的所有 "special"字符?

c# - 返回的数据类型因表中的数据而异

mysql - 将文本文件中的数据导入到sql表中

c# - 通过编程使用时,我的插入命令不会更改数据库

java - 检测 java.lang.Class.getResourceAsStream() 打开的目录

java - 保存到 mysql 数据库时出现 jbutton 问题

java - 如何使用Proteus Android Layout Engine实现级联资源