Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jTDS + stored procedures + prepareSQL = nesting level error?

Situation
I have a (Tomcat) Java web application using jTDS to connect to a MSSQL 2008 database. This Java application executes 99% of its MSSQL stored procedures using user input.

Problem
The jTDS driver replies sometimes (at different places in the application) with error:

Maximum stored procedure, function, trigger, or view nesting level exceeded (limit 32).

We can avoid this by adding prepareSQL=0 to the jTDS connection string. Then the error goes away everywhere, but with all other values of prepareSQL, the error stays. I don't know how many stored procedure nesting levels jTDS adds, but apparently it's too much for our application.

Questions

  1. With only stored procedures to execute, of course using Prepared Statements in the Java code, how much effect does prepareSQL=3 (or prepareSQL=0) have for us? In other words: on every website I find people say "Never use prepareSQL=0 in production environments", is that also applicable to this situation?

  2. If prepareSQL=0 is not a recommended solution, a security issue, etc., we should maybe look for another driver. jTDS has not been updated the past 2 years and Microsoft has a driver for JDBC 4.0. I can't find any benchmarks or comparisons between jTDS and Microsoft's JDBC 4.0 driver though. With Microsoft's 2.0 and 3.0 drivers, the general opinion seemed to be that jTDS is faster, better, more efficient. Is that still the case with JDBC 4.0 or has Microsoft passed its competitor in this?

like image 473
bartlaarhoven Avatar asked May 03 '12 07:05

bartlaarhoven


1 Answers

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.

like image 190
ijrandom Avatar answered Nov 02 '22 08:11

ijrandom