我为DB2提供了以下缩写格式的SQL:
Select ...
From ...
Where ... ((COL1 IS NULL) And ('' = ?)) ...
Order By ...
如果针对COL1的输入为空白,则此SQL的粗略目的是返回Null记录。
但是,如果我尝试将“RED”绑定到占位符,则会收到CLI0109E错误,指示“字符串数据右截断”。我相信正在发生的事情是DB2已经确定SQL中的''文字是长度为0的列,因此尝试比较长度为3的绑定参数(在'RED'的情况下)会导致截断错误。这是有道理的。
如果我将SQL更改为:((COL1 IS NULL) And ('{10 spaces}' = ?))
,它可以正常工作。
如果我将SQL更改为:((COL1 IS NULL) And (CAST('' AS VARCHAR(32767)) = ?))
,它可以正常工作。
是否存在我缺少的驱动程序设置或SQLBindParameters设置导致DB2将''解释为零长度列?
我通过Oracle和SQLServer运行相同的SQL并且它们工作正常,这告诉我他们将''解释为不同的东西,并且可能默认将SQL中的所有文字视为VARCHAR(32767)或其他东西。
感谢您的帮助。
答案 0 :(得分:1)
这个问题的答案似乎是DB2在确定文字的数据类型和大小时的工作方式。
从我发现的情况来看,这里要理解的概念似乎是隐含的和明确的CASTing。由于没有为空字符串文字提供显式CAST,并且在比较谓词的右侧没有可用的进一步信息(仅存在参数占位符且它没有提供确定的大小信息),DB2将隐式转换为文字的大小,在这种情况下是CHAR(1)(或者VARCHAR(1),我在这一点上并不完全确定。)
因此,它不是CLI驱动程序问题或怪癖,也不是SQLBindParameters问题。 CAST的显式CAST('作为VARCHAR(nn))似乎是避免CLI0109E错误的正确解决方案。
对于它的价值,严格根据我的经验,在这些平台上运行相同的SQL时,Oracle和SQLServer的行为似乎与DB2不同。他们隐含的CAST,没有可用的大小信息,似乎是VARCHAR(大)。但是明确的CAST也适用于他们。