我指的具体代码是:
AND (
(','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.' ||
CASE WHEN log.subtype is null
THEN ' '
ELSE log.subtype
END || ',%')
OR (','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.-1,%')
OR (to_char(log.logtypeid) LIKE
CASE
WHEN to_char('~[gpv:lt]') = '-1'
THEN '%'
ELSE ','||to_char('~[gpv:lt]')||','
END)
)
任何澄清都会很棒。谢谢!
答案 0 :(得分:1)
%
被称为Wildcard character
。更多信息here。
答案 1 :(得分:1)
那些-1,%
是字符串文字,用于根据几个内容和某些列的值构建LIKE
条件。该声明显示了对如何在Oracle中使用字符串文字的基本误解。
以此为例:
','||to_char('~[gpv:lt]')||',' LIKE '%,' || to_char(log.logtypeid) || '.-1,%'
to_char('~[gpv:lt]')
完全没用,因为它只是将字符串常量'~[gpv:lt]'
转换为...字符串。这部分可以简化为:
',~[gpv:lt],' LIKE '%,' || to_char(log.logtypeid) || '.-1,%'
基本上说:
将字符串常量',~[gpv:lt],'
与以下
'%,'
log.logtypeid
转换为varchar
'.-1,%'
因此,假设log.logtypeid
包含值42
,则会生成条件
',~[gpv:lt],' LIKE '%,42.-1,%'
如果列log.logtypeid
包含~[gpv:lt]
之类的值,则只能匹配。这些名为" id"的列会有点令人困惑。通常不包含"结构化数据"像那样。
如果我不得不猜测,我会说数据模型严重去标准化,这些列存储逗号分隔的结构化数据(甚至可能是结构化的键/值对)。
其他条件做类似的事情。
答案 2 :(得分:0)
让我们从这个表达开始:
(','||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
字符串是单个值,并且您想知道列表是否{{1},就可以使用此比较}}包含值a
。
要知道为什么会这样写,请先看看这种尝试更简单:
b
我们选择a LIKE '%'||b||'%'
,在正面和背面放置一个通配符,然后匹配b
。如果a
例如a
且1,2,3
为b
,则会出现这种情况。如果2
为a
且12,34,56
为b
,则不幸也是如此。 2
不进行逗号分隔列表解析,只进行字符串匹配。
接下来你可以试试这个:
LIKE
如果a LIKE '%,'||b||',%'
为b
,则模式为2
- 它将匹配包含%,2,%
的任何字符串,因此,2,
= {{对于a
= 1,2,3
,1}}和false。不幸的是,a
= 12,34,56
也是错误的,因为2之前没有逗号,a
= 2,3,4
则为假,因为2没有逗号在它之后。
对于下一次改进,有两种方法可以选择。您可以使用单独的模式案例来匹配a
的开头,中间和结尾的0,1,2
(如果你这样做,使用正则表达式将有助于使其可读!)
另一种方法是修改b
以匹配现有模式。我们没有匹配a
或a
,因为列表的第一个元素和列表的最后一个元素没有逗号。但是如果我们在匹配之前在0,1,2
的开头添加一个逗号,那么列表的第一个元素将用逗号包围!并在2,3,4
的末尾添加另一个逗号,以确保最后一个元素也被逗号包围。
a
现在a
为','||a||',' LIKE '%,'||b||',%'
且a
为0,1,2
时,b
表达式变为:
2
这是一场比赛!第一个通配符吸收LIKE
并找到',0,1,2,' LIKE '%,2,%'
。最后一个通配符匹配末尾的零长度子字符串,这是允许的。