我偶然发现了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
这为什么会失败-以及如何解决?
我尝试过的替代方法
SELECT trim( name_long || cast( ' ' as varchar) || name2_long ) from test;
(相同错误)答案 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