1

I've got SQL for DB2 of the following abbreviated format:

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

The rough purpose of this SQL is to return Null records if the input against COL1 is blank.

However, if I try to bind 'RED' to the placeholder, I get a CLI0109E error indicating 'string data right truncation.' I believe what is happening is that DB2 has decided that the '' literal in the SQL is a column of length 0, and so trying to compare a bound parameter of length 3 (in the case of 'RED') causes the truncation error. This would make sense.

If I change the SQL to: ((COL1 IS NULL) And ('{10 spaces}' = ?)), it works fine.

If I change the SQL to: ((COL1 IS NULL) And (CAST('' AS VARCHAR(32767)) = ?)), it works fine.

Is there a driver setting, or an SQLBindParameters setting that I'm missing that's causing DB2 to interpret the '' as a zero-length column?

I run the same SQL through Oracle and SQLServer and they work fine, which tells me they interpret '' as something different, and maybe by default treat all literals in the SQL as VARCHAR(32767) or something.

Thanks for any help.

4

1 回答 1

1

这个问题的答案似乎是 DB2 在确定字面量的数据类型和大小时的工作方式。

根据我的发现,这里要理解的概念似乎是隐式和显式的 CAST。由于没有为空字符串文字提供显式 CAST,并且比较谓词的右侧没有更多可用信息(只有参数占位符存在并且它没有提供明确的大小信息),DB2 将隐式转换为文字的大小,在这种情况下是 CHAR(1)(或者可能是 VARCHAR(1),我对此并不完全确定)。

因此,这不是 CLI 驱动程序问题或怪癖,也不是 SQLBindParameters 问题。CAST('' as VARCHAR(nn)) 的显式 CAST 似乎是避免 CLI0109E 错误的正确解决方案。

就其价值而言,严格根据我的经验,当在这些平台上运行相同的 SQL 时,Oracle 和 SQLServer 的行为似乎与 DB2 不同。它们隐含的 CAST,没有任何可用的大小信息可供绘制,似乎是 VARCHAR(large)。但是显式 CAST 也同样适用于它们。

于 2013-03-28T19:31:34.950 回答