具有空间文字的较长varchars的DB2字符串连接失败

时间:2018-06-20 13:14:22

标签: db2

我偶然发现了varchar串联和trim函数的奇怪问题。我正在使用DB2 11.1.1.2。

我的表由长和短的varchar组成:

CREATE TABLE test (
id integer,
name_short varchar(200),
name2_short varchar(200),
name_long varchar(2000),
name2_long varchar(2000)
)

有效的方法:

如果我将两个(较短的)varchars串联起来并将它们传递给TRIM函数,它将很好用:

SELECT trim( name_short ||  name2_short ) from test;

在两者之间添加空格也是没有问题的:

SELECT trim( name_short || ' ' ||  name2_short ) from test;

将两个较长的varchars串联也可以:

SELECT trim( name_long || name2_long ) from test;

什么不起作用:现在添加空格失败!

SELECT trim( name_long || ' ' || name2_long ) from test;

结果:

  

未处理该语句,因为例程“ SYSIBM.TRIM”的位置“ string-expr”中参数的参数的数据类型,长度或值不正确。参数名称:“”。SQLCODE = -171,SQLSTATE = 42815,DRIVER = 4.16.53

这为什么会失败-以及如何解决?

  • Trim希望将varchar作为要修剪的表达式
  • 根据db2 docs for the concatenation operator,连接两个varchar的结果应为:
    • 对于z / OS:varchar,其长度等于操作数长度的总和(如果较小,则为32764)。
    • 对于LUW版本(Linux Unix Windows):Longvarchar 编辑:已添加Linux版本

我尝试过的替代方法

  • 强制转换字符串文字:SELECT trim( name_long || cast( ' ' as varchar) || name2_long ) from test;(相同错误)
  • 在将整个表达式传递给修剪之前,将整个表达式铸造到varchar
  • 注意:将较长的列之一更改为2001长度将使第三个示例失败!

3 个答案:

答案 0 :(得分:1)

正在发生-171 sqlcode,因为Db2-LUW可能会将name_long || ' ' || name2_long转换为TRIM不喜欢的数据类型LONG VARCHAR。 如果您这样显式地进行铸造,则可能会得到不同的结果:

SELECT trim( varchar(name_long || ' ' || name2_long) ) from test;

您还可以通过以下方法检查Db2在做什么: describe select name_long || ' '||name2_long from test;

我尝试使用Db2-LUW v11.1.3.3并强制转换为VARCHAR会产生正确的结果。

因此,您可能要应用最新的修订包并重试。

答案 1 :(得分:1)

正如mao所指出的,“组合长度属性”大于4000的列CONCAT返回LONG VARCHAR。请参阅此页上的表1 https://www.ibm.com/support/knowledgecenter/en/SSEPGG_11.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0000736.html 因此您需要将类型显式转换为VARCHAR

有趣的是,在NPS兼容模式下的Db2 Warehouse上不需要强制转换。

set sql_compat='NPS';
SELECT trim( name_long || ' ' || name2_long ) from test;

答案 2 :(得分:0)

CHR(32)可以正常工作,例如此示例。

 select trim(authid)||chr(32)||trim(authidtype)from sysibmadm.authorizationids

输出。

PUBLIC G
SYSROLE_AUTH_DBADM R
SYSROLE_AUTH_EXPLAIN R