1

JDBC の制限を回避するためのパターンを実装しています。プリペアド ステートメントの場合、JDBC はプレースホルダーの数を 2100 に制限しています。これを回避するために、2100 以上の値を含む xml 文字列を使用し、関数 tf_splitxml を使用して SQL Server 側で解析しています。準備済みステートメントを使用する〜4 Javaメソッドに対してこれを行っています。

この tf_splitxml は、すべての値を含む単一の列「トークン」を構築するだけです。したがって、次のxml文字列:

'<node><value>1</value><value>2</value></node>' 

値が 1 と 2 の 2 つの行を含む列に変換されます。

このパターンは、select ステートメントではうまく機能しているように見えますが、update ステートメントでは失敗しています。一般的なパターンは次のとおりです。

declare @xml xml; set @xml = ?; --Replaced with xml string in PreparedStatement

update tableX
...
where ids in (select token from tf_splitxml(@xml));

nvarchar 値をデータ型 int に変換するときに変換に失敗したことがわかります。[上記の xml 文字列の場合]。奇妙なことに、準備されたステートメントによって設定されたクエリを抽出すると、SQL Server で完全に実行できます。

私の考え:

  1. 4 つの方法のうち、3 つはこの xml パターンを使用して機能します。これら 3 つはすべて select ステートメントであり、executeQuery() を使用します。失敗した 4 番目のメソッドは update ステートメントで、executeUpdate() を使用します。おそらく問題は、準備されたステートメントがSQLをプリコンパイルする方法に関係していますか?

私が試したこと:

  1. tf_splitxml から生成されたトークンを保持できるテーブルを作成しました。失敗したメソッドの場合、JDBC がエラーをスローする前に tf_splitxml が呼び出されることはありません。

  2. Java 側では、ps.setString(index, convertToXML(idsArray)) を使用しています。@xml が文字列ではない (xml 変数として宣言されている) 場合でも、これは最初の 3 つのメソッドで機能します。これを SQLXML オブジェクトに切り替えてみましたが、役に立ちませんでした。私はまだ同じ 3/4 メソッドを適切に動作させています。

  3. 準備したすべてのクエリを SQL Server エディター内で直接実行できます。

よろしくお願いします!:)

4

1 に答える 1