1

次の省略形式のSQLforDB2があります。

Select ...
From ...
Where ... ((COL1 IS NULL) And ('' = ?)) ...
Order By ...

このSQLの大まかな目的は、COL1に対する入力が空白の場合にNullレコードを返すことです。

ただし、「RED」をプレースホルダーにバインドしようとすると、「文字列データの右切り捨て」を示すCLI0109Eエラーが発生します。何が起こっているのかというと、DB2はSQLの''リテラルが長さ0の列であると判断したため、長さ3('RED'の場合)のバインドされたパラメーターを比較しようとすると、切り捨てエラーが発生します。これは理にかなっています。

SQLを:に変更すると、正常に((COL1 IS NULL) And ('{10 spaces}' = ?))機能します。

SQLを:に変更すると、正常に((COL1 IS NULL) And (CAST('' AS VARCHAR(32767)) = ?))機能します。

DB2が''を長さゼロの列として解釈する原因となっているドライバー設定、または欠落しているSQLBindParameters設定はありますか?

私はOracleとSQLServerを介して同じSQLを実行し、それらは正常に動作します。これは、''を別のものとして解釈し、デフォルトでSQL内のすべてのリテラルをVARCHAR(32767)などとして処理することを示しています。

助けてくれてありがとう。

4

1 に答える 1

1

この質問に対する答えは、これが、リテラルのデータ型とサイズを決定するときにDB2が機能する方法であるように思われます。

私が見つけたものから、ここで理解する概念は暗黙的および明示的なキャストであるように思われます。空の文字列リテラルに対して明示的なCASTが提供されておらず、比較述部の右側に利用可能な追加情報がなかったため(パラメーター・プレースホルダーのみが存在し、明確なサイズ情報を提供しない)、DB2は暗黙的ににキャストします。リテラルのサイズ、この場合はCHAR(1)(または、おそらくVARCHAR(1)、この点については完全にはわかりません)。

したがって、これはCLIドライバーの問題や癖でも、SQLBindParametersの問題でもありません。CAST('' as VARCHAR(nn))の明示的なCASTは、CLI0109Eエラーを回避するための正しい解決策のようです。

私の経験に厳密に基づくと、OracleとSQLServerは、これらのプラットフォームで同じSQLを実行した場合、DB2とは異なる動作をするように見えます。それらの暗黙のCASTは、描画に使用できるサイズ情報がない場合、VARCHAR(large)のように見えます。ただし、明示的なCASTも同様に機能します。

于 2013-03-28T19:31:34.950 に答える