首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >DB2 LIKE运算符的奇怪长度限制

DB2 LIKE运算符的奇怪长度限制
EN

Stack Overflow用户
提问于 2012-02-11 03:57:16
回答 3查看 3.1K关注 0票数 4

我发现了SQLv9.7和DB2 LIKE操作符的一个有趣的问题。看看这个:

代码语言:javascript
运行
复制
-- this works and returns one record
select 1 
from SYSIBM.DUAL
where 'abc' like concat('a', 'bc') 

-- this doesn't work
select 1 
from SYSIBM.DUAL
where 'abc' like concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000)))

-- It causes this error (from JDBC):
-- No authorized routine named "LIKE" of type "FUNCTION" having compatible 
-- arguments was found.. SQLCODE=-440, SQLSTATE=42884, DRIVER=4.7.85

我对长度进行了调整,似乎只要长度加起来大于4000,问题就会出现。如果我将整个连接的字符串“截断”回长度4000,这个问题就消失了:

代码语言:javascript
运行
复制
select 1 
from SYSIBM.DUAL
where 'abc' like 
  cast(concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000)))
  as varchar(4000))

有趣的是,它似乎真的与CONCAT函数有关。以下方法也适用:

代码语言:javascript
运行
复制
select 1 
from SYSIBM.DUAL
where 'abc' like cast('abc' as varchar(32672))

有没有人遇到过这样的问题?这是DB2中的一个bug吗?或者是一些没有记录的限制?注意:我在这里发现了类似的问题:

https://www-304.ibm.com/support/docview.wss?uid=swg1PM18687

考虑到IBM的另一个产品在2010年为这个问题创建了一个解决方案,我猜这不是一个真正的bug,否则它会在同一时间被修复吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-02-12 00:05:34

编辑:啊哈!

在信息中心搜索有关VARCHAR的另一方面的知识时,我在character data type page上发现了这个有趣的信息

将VARCHAR作为参数的SYSFUN模式中的函数将不接受长度大于4000字节的VARCHAR作为参数。但是,这些函数中的许多函数还具有接受CLOB(1M)的替代签名。对于这些函数,用户可以显式地将4000多个VARCHAR字符串转换为CLOB,然后将结果重新转换回所需长度的VARCHAR。

所以,它看起来像是DB2的一个众所周知的“特性”。

我做了一些额外的测试,看起来上面提到的“变通办法”适用于Linux/Unix/Windows上的DB2,但不适用于大型机上的DB2。

离开信息中心的SQL and XML Limits页面,如果您查看表7(第三行),它表明包含具有4k页面大小的表空间的所有开销的行的最大长度是4005字节。

我的猜测是SYSIBM.DUAL在一个4k页面大小的表空间中,这导致了您的错误。您可以查看SYSCAT.TABLESPACES,它可以确认或否认这一怀疑。

您可以使用如下查询来获取信息:

代码语言:javascript
运行
复制
SELECT ts.PAGESIZE
FROM SYSCAT.TABLESPACES ts
JOIN SYSCAT.TABLES tb
  ON tb.TBSPACEID = ts.TBSPACEID
WHERE tb.TABSCHEMA = 'SYSIBM'
  AND tb.TABNAME   = 'DUAL'
票数 2
EN

Stack Overflow用户

发布于 2013-08-20 04:02:18

真正的啊哈!来了。

首先,根据rules for the concatenation operator结果类型,连接具有组合长度为4000字节或更小的两个VARCHAR产生该组合长度的VARCHAR,例如concat(varchar(2000), varchar(2000)) = varchar(4000)。连接两个合并长度为4001字节或更大的VARCHAR将生成长度为32 700的长VARCHAR。尽管LONG VARCHAR类型已被弃用,但我猜连接行为仍然使用遗留逻辑。

代码语言:javascript
运行
复制
$ db2 describe "values concat(cast('a' as varchar(2000)), cast('bc' as varchar(2000)))"

Column Information

Number of columns: 1

SQL type              Type length  Column name                     Name length
--------------------  -----------  ------------------------------  -----------
448   VARCHAR                4000  1                                         1


$ db2 describe "values concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000)))"

Column Information

Number of columns: 1

SQL type              Type length  Column name                     Name length
--------------------  -----------  ------------------------------  -----------
456   LONG VARCHAR          32700  1     

其次,LIKE predicate期望模式表达式是一个最大长度为32672字节的VARCHAR。

随后,当您无意中尝试使用LONG VARCHAR作为模式表达式时,会得到一个错误。与其说是关于操作数的长度,不如说是关于它的数据类型。下面的代码应该可以工作:

代码语言:javascript
运行
复制
select 1 
from SYSIBM.DUAL
where 'abc' like 
   cast(concat(cast('a' as varchar(2001)), cast('bc' as varchar(2000)))
   as varchar(32672))
票数 5
EN

Stack Overflow用户

发布于 2012-02-11 05:34:34

这可能与表所在表空间的行大小有关吗?

我认为如果一个VARCHAR变量超出了正在查询的表的行大小,那么它必须被声明为LONG DB2,存储在表数据的其余部分之外,并被指针引用,并且不再可能进行LIKE查询。但我已经有几年没用过DB2了。:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9234021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档