2012-05-03 9 views
7

状況
MSSQL 2008データベースに接続するためにjTDSを使用する(Tomcat)Java Webアプリケーションがあります。このJavaアプリケーションは、ユーザー入力を使用してMSSQLストアドプロシージャの99%を実行します。
jTDS +ストアドプロシージャ+ prepareSQL =ネストレベルエラー?

問題のjTDSドライバはエラーで(アプリケーション内の別の場所で)時々返信:

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

我々はのjTDS接続文字列にprepareSQL=0を追加することでこの問題を回避することができます。その後、エラーはどこでも消えますが、他のすべての値がprepareSQLの場合、エラーはそのまま残ります。 jTDSが追加するストアドプロシージャの入れ子レベルの数はわかりませんが、明らかにアプリケーションにとっては大きすぎます。 、Javaコードでプリペアドステートメントを使用して、もちろん、prepareSQL=3(またはprepareSQL=0)が私たちのためにどれだけの影響を

質問実行するための唯一のストアドプロシージャで

  1. がありますか?言い換えれば、すべてのWebサイトで「生産環境で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

いいえ、私たちは(まだ)持っていません。アプリケーションの2つの異なる場所でアプリケーションの2つの異なる実装でこのエラーが発生しましたが、発生したときには頑固で、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(); 

あなたは0以外の値にprepareSQLを設定した場合、それは「最大のストアド・プロシージャ、ファンクション、トリガ、またはビューの入れ子で失敗しますレベルを超えました(制限32)。なぜあなたのコードが多くのネストを使用するのかを知る必要がありますか? prepareSQL = 0によって、mssqlが各実行時にSQLを解析するために強制的にstamementsを使用するのを防ぎます。ステートメントの実行時間がステートメントの圧縮時間よりもはるかに長い場合は大きな問題ではありません(ストアドプロシージャを10秒実行するとE.G.コンパイルに10ms以上かかる場合は問題ありません)。あなたが同じ問題を抱えているので、ドライバーの変更は役に立たない。

関連する問題