2013-03-27 100 views
1

我有SQL以下简写格式的DB2结合:DB2参数字面比较

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

这个SQL的粗糙的目的是返回空记录,如果对COL1输入是空白。

但是,如果我尝试将“RED”绑定到占位符,则会出现CLI0109E错误,指示“字符串数据右截断”。我相信发生的事情是DB2已经决定SQL中的'literal'是一个长度为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)或其他东西。

感谢您的任何帮助。

回答

1

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

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

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

值得一提的是,严格根据我的经验,Oracle和SQLServer在这些平台上运行相同的SQL时似乎表现出与DB2不同的行为。它们隐含的CAST在没有可用的任何可用大小信息的情况下似乎是VARCHAR(大)。但是明确的CAST对他们也同样适用。