让我们从这个表达式开始:
(','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.' ||
CASE WHEN log.subtype is null
THEN ' '
ELSE log.subtype
END || ',%')
这是这个成语的一个例子:
','||a||',' LIKE '%,'||b||',%'
其中a
是您的lt
参数,以及b
“类型点子类型”字符串。a
只要您有一个以逗号分隔的值列表的字符串和一个b
为单个值的字符串,并且您想知道该列表是否a
包含该值,就可以使用此比较b
。
要了解它为什么这样写,首先看一下这个更简单的尝试:
a LIKE '%'||b||'%'
我们取b
,在前面和后面放一个通配符,然后匹配a
。a
例如,如果 is1,2,3
和b
is ,这将是正确的2
。不幸的是,如果a
is12,34,56
和b
is 也是如此2
。LIKE
不做逗号分隔的列表解析,只是字符串匹配。
所以接下来你可以试试这个:
a LIKE '%,'||b||',%'
现在如果b
是2
,则模式是%,2,%
- 它将匹配任何包含的字符串,,2,
因此对于 = 为真,对于=a
为1,2,3
假。不幸的是,=也是错误的,因为 2 前面没有逗号,=错误,因为 2 后面没有逗号。a
12,34,56
a
2,3,4
a
0,1,2
对于下一个改进,有两种方法可以走。您可以使用单独的模式案例b
在开头、中间和结尾进行匹配a
(如果您这样做,使用正则表达式将有助于使其可读!)
另一种方法是修改a
以匹配现有模式。我们不匹配0,1,2
或者2,3,4
是因为列表的第一个元素和列表的最后一个元素没有被逗号包围。但是如果我们a
在匹配之前在开头添加一个逗号,那么列表的第一个元素将被逗号包围!并在末尾添加另一个逗号以a
确保最后一个元素也被逗号包围。
','||a||',' LIKE '%,'||b||',%'
现在当a
is0,1,2
和b
is时2
,LIKE
表达式变为:
',0,1,2,' LIKE '%,2,%'
这是一场比赛!第一个通配符吸收了,0,1
并且,2,
找到了。最后一个通配符匹配末尾的零长度子字符串,这是允许的。