-4

我具体指的代码是:

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)  
)

任何澄清都会很棒。谢谢!

4

3 回答 3

1

%被称为Wildcard character. 更多信息在这里

于 2014-08-21T12:50:07.983 回答
0

这些-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],'与以下连接的结果进行比较

  1. 常数'%,'
  2. 列的值log.logtypeid转换为varchar
  3. 常数'.-1,%'

因此,假设log.logtypeid包含42生成条件的值

',~[gpv:lt],' LIKE '%,42.-1,%'

仅当列log.logtypeid包含类似 的值时才匹配~[gpv:lt]。这会有点令人困惑,因为名为“id”的列通常不包含这样的“结构化数据”。

如果我不得不猜测,我会说数据模型被严重去规范化,并且这些列存储逗号分隔的结构化数据(甚至可能是结构化的键/值对)。

其他条件做类似的事情。

于 2014-08-21T13:51:25.263 回答
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为单个值的字符串,并且您想知道该列表是否a包含该值,就可以使用此比较b

要了解它为什么这样写,首先看一下这个更简单的尝试:

a LIKE '%'||b||'%'

我们取b,在前面和后面放一个通配符,然后匹配aa例如,如果 is1,2,3bis ,这将是正确的2。不幸的是,如果ais12,34,56bis 也是如此2LIKE不做逗号分隔的列表解析,只是字符串匹配。

所以接下来你可以试试这个:

a LIKE '%,'||b||',%'

现在如果b2,则模式是%,2,%- 它将匹配任何包含的字符串,,2,因此对于 = 为真,对于=a1,2,3假。不幸的是,=也是错误的,因为 2 前面没有逗号,=错误,因为 2 后面没有逗号。a12,34,56a2,3,4a0,1,2

对于下一个改进,有两种方法可以走。您可以使用单独的模式案例b在开头、中间和结尾进行匹配a(如果您这样做,使用正则表达式将有助于使其可读!)

另一种方法是修改a以匹配现有模式。我们不匹配0,1,2或者2,3,4是因为列表的第一个元素和列表的最后一个元素没有被逗号包围。但是如果我们a在匹配之前在开头添加一个逗号,那么列表的第一个元素被逗号包围!并在末尾添加另一个逗号以a确保最后一个元素也被逗号包围。

','||a||',' LIKE '%,'||b||',%'

现在当ais0,1,2bis时2LIKE表达式变为:

',0,1,2,' LIKE '%,2,%'

这是一场比赛!第一个通配符吸收了,0,1并且,2,找到了。最后一个通配符匹配末尾的零长度子字符串,这是允许的。

于 2014-08-21T13:57:23.473 回答