2012-05-03 5 views
7

Ситуация
У меня есть (Tomcat) Java-приложение с использованием jTDS для подключения к базе данных MSSQL 2008. Это приложение Java выполняет 99% хранимых процедур MSSQL с использованием пользовательского ввода.jTDS + хранимые процедуры + prepareSQL = ошибка уровня вложенности?

Проблема
Водитель jTDS отвечает иногда (в разных местах в приложении) с ошибкой:

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

Мы можем избежать этого путем добавления prepareSQL=0 в строке соединения jTDS. Затем ошибка исчезает везде, но со всеми остальными значениями prepareSQL ошибка остается. Я не знаю, сколько добавленных уровней хранения вложенных процедур jTDS добавляется, но, судя по всему, это слишком много для нашего приложения.

Вопросы

  1. С только хранимых процедур для выполнения, конечно, используя подготовленные заявления в коде Java, сколько эффект делает 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 передала конкуренту в этом?

+0

Вам удалось определить это поведение для какой-либо конкретной процедуры или это кажется случайным? – heikkim

+0

Нет, у нас пока нет (пока). Мы видели эту ошибку в двух разных реализациях нашего приложения в двух разных местах приложения, но когда это произошло, оно было упрямым и могло быть разрешено только с помощью решения prepareSQL = 0. – bartlaarhoven

ответ

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 

и 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, то потерпит неудачу с «Maximum хранимой процедуры, функции, триггера, или вид вложенности превышен уровень (предел 32) ». Вам нужно выяснить, почему ваш код использует так много гнездования? С помощью prepareSQL = 0 вы предотвращаете использование mssql для stamements и тех, которые вынуждают синтаксический анализ SQL при каждом выполнении. Это не большая проблема, если время выполнения инструкции намного больше, чем время выполнения команды (E.G., если хранимый процесс обрабатывает 10 секунд, это не проблема, если компиляция заняла 10 мсек.). Изменение драйвера не поможет, потому что у вас будут одинаковые проблемы.

Смежные вопросы