0

フォームの大規模な条件に対してjOOQ統合テストを実行しています

WHERE x IN (:1, :2, :3, :4, ..., :3001, :3002)

上記の例は、条件に多くのバインド変数があることを示していINます。Oracle には、IN 条件の括弧間の値 (バインド値またはインライン値) が 1000 というよく知られた制限があります。解決策は簡単です。次のように書くだけです。

WHERE x IN (:1, :2, :3, :4, ..., :1000) OR x IN (:1001, ...)

一方、Sybase ASE 15.5 と SQL Server 2008 R8 では、バインド値の数に全体的な制限があるようです。それぞれ、Sybase ASE では 2000、SQL Server では 2100 です。つまり、これら2つのデータベースのバインド値を使用して上記の条件を分割/変換する方法はないようです。すべてのバインド値をインライン化する以外に、その問題を回避する方法はありますか?

4

2 に答える 2

1

テーブルタイプを作成してから言うとIN (SELECT column FROM @variableThatIsMyTableType)、まったく制限されません。

MSDN を逆流させるつもりはありません。MSDN では、テーブルの型とテーブルの値を持つパラメーターについて説明しています

次に生成する SQL は次のようになります。

DECLARE @variableThatIsMyTableType mySchema.myTableType
INSERT @variableThatIsMyTableType VALUES (1)
INSERT @variableThatIsMyTableType VALUES (2)
EXEC proc @variableThatIsMyTableType

ただし、これを C# および SqlClient から送信すると、「単純な計画」と呼ばれるものが作成されます。TVP と単純な計画については、ここここで読むことができます。SQL ダイレクト経由で実行すると、プランがキャッシュされるため、マイレージは異なる場合があります。

于 2012-06-29T22:57:24.383 に答える
0

これを最終的にjOOQに実装した方法は、制限に遭遇したときにa を使用してControlFlowException、バインド値で SQL のレンダリングを中止することです。制限は次のとおりです。

  • SQLite: 999
  • イングレス 10.1.0: 1024
  • サイベース ASE 15.5: 2000
  • SQL Server 2008: 2100

これについては、こちらのブログでも取り上げています。

この制限にControlFlowException達すると、クエリ レンダリング サイトでキャッチされ、すべてのバインド値がインライン化されて再レンダリングされます。これは常に機能します (もちろん、クエリ サイズ制限に達するまで)。

このような非常に動的な SQL で実行計画を実際に再利用できる可能性は低いため、インライン化されたバインド値と発生する反復的なハード解析は問題ないと想定しています。

于 2015-01-11T07:50:31.667 に答える