较长的varchar与空格literal的DB2字符串连接失败

较长的varchar与空格literal的DB2字符串连接失败,db2,Db2,我偶然发现varchar连接和trim函数有一个奇怪的问题。我正在使用DB211.1.1.2 我的桌子由短的和长的瓦查尔组成: 什么有效: 如果我连接两个(较短的)varchar并将它们传递给TRIM函数,它就可以正常工作: SELECT trim( name_short || name2_short ) from test; 在以下各项之间添加空格也没有问题: SELECT trim( name_short || ' ' || name2_short ) from test; 将两个

我偶然发现varchar连接和trim函数有一个奇怪的问题。我正在使用DB211.1.1.2

我的桌子由短的和长的瓦查尔组成:

什么有效:

如果我连接两个(较短的)
varchar
并将它们传递给
TRIM
函数,它就可以正常工作:

SELECT trim( name_short ||  name2_short ) from test;
在以下各项之间添加空格也没有问题:

SELECT trim( name_short || ' ' ||  name2_short ) from test;
将两个较长的Varchar连接起来也很有效:

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作为要修剪的表达式
  • 根据,连接两个VARCHAR的结果应为:
    • 对于z/OS:长度等于操作数长度之和的varchar(如果较小,则为32764)
    • 对于LUW版本(Linux Unix Windows):添加了Longvarchar编辑:Linux版本
我尝试过的备选方案

  • 转换字符串文字:
    从测试中选择trim(name_long | | | cast(''as varchar)| | name2_long)(相同错误)
  • 在将整个表达式传递给trim之前,将其强制转换为varchar
  • 注意:将其中一个较长的列的长度更改为2001将导致第三个示例失败
之所以出现-171 sqlcode,是因为DB2LUW可能正在将
name|u long | |“”| name2_long
转换为一个数据类型long VARCHAR,这是TRIM不喜欢的。 如果显式地按以下方式进行强制转换,可能会得到不同的结果:

从测试中选择trim(varchar(name|long | |“”| | name2|long))

您还可以通过以下方式检查Db2正在做什么:
描述从测试中选择名称| | |“| |名称2 |长

我在DB2LUWv11.1.3.3上进行了尝试,并将其转换为VARCHAR得到了正确的结果


因此,您可能希望应用最新的补丁包并重试。

之所以出现-171 SQL代码,是因为Db2 LUW可能正在将
name_long | |“”| name2_long
转换为数据类型long VARCHAR,这是TRIM不喜欢的。 如果显式地按以下方式进行强制转换,可能会得到不同的结果:

从测试中选择trim(varchar(name|long | |“”| | name2|long))

您还可以通过以下方式检查Db2正在做什么:
描述从测试中选择名称| | |“| |名称2 |长

我在DB2LUWv11.1.3.3上进行了尝试,并将其转换为VARCHAR得到了正确的结果


因此,您可能希望应用最新的fixpack并重试。

正如mao所指出的,如果列的“组合长度属性”大于4000,则返回一个
长VARCHAR
。见本页表1 因此,您需要显式地将类型强制转换为
VARCHAR

有趣的是,在NPS compat模式下的Db2仓库上不需要强制转换

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

正如mao所指出的,“组合长度属性”大于4000的列的
CONCAT
返回
LONG VARCHAR
。见本页表1 因此,您需要显式地将类型强制转换为
VARCHAR

有趣的是,在NPS compat模式下的Db2仓库上不需要强制转换

set sql_compat='NPS';
SELECT trim( name_long || ' ' || name2_long ) from test;
CHR(32)运行良好,如本例所示

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

PUBLIC G
SYSROLE_AUTH_DBADM R
SYSROLE_AUTH_EXPLAIN R
CHR(32)运行良好,如本例所示

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

PUBLIC G
SYSROLE_AUTH_DBADM R
SYSROLE_AUTH_EXPLAIN R