【问题标题】:What does '%,' and '.-1,%' and ',%' or '%,' mean in SQL/Oracle?'%,' 和 '.-1,%' 和 ',%' 或 '%,' 在 SQL/Oracle 中是什么意思?
【发布时间】:2014-08-21 12:42:25
【问题描述】:

我具体指的代码是:

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

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

【问题讨论】:

  • % 是 SQL 通配符,类似于 dirls 命令的 *
  • 投了反对票,没有表现出努力。谷歌搜索'百分比登录 sql'....
  • 我希望我能对你不理解英语投反对票。我知道 % 是一张通配符。我不知道的是逗号、句号的使用,以及它们何时与 % 一起使用
  • 对于那些不知道的人:~[gpv:lt] 的东西来自 PowerSchool 标签语言。它从 URL 或 POST 数据中插入 lt 参数的值。这是我在 stackexchange 上看到的第一个 powerschool 问题……我添加了一个标签。

标签: sql oracle powerschool


【解决方案1】:

% 被称为Wildcard character。更多信息here

【讨论】:

    【解决方案2】:

    让我们从这个表达式开始:

    (','||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 是否包含值@,就可以使用此比较987654329@.

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

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

    我们取b,在前后放置一个通配符,匹配a。如果a 是例如1,2,3 并且b2,这将是正确的。如果a12,34,56 并且b2,这也是不幸的。 LIKE 不做逗号分隔的列表解析,只做字符串匹配。

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

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

    现在如果b2,则模式是%,2,% - 它将匹配任何包含,2, 的字符串,因此a=1,2,3 为真,a=@987654350 为假@。不幸的是,a=2,3,4 也是错误的,因为 2 前面没有逗号,而 a=0,1,2 错误,因为 2 后面没有逗号。

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

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

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

    现在当a0,1,2 并且b2 时,LIKE 表达式变为:

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

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

    【讨论】:

    • 很好的解释。唯一仍然没有意义的是,您的示例中的 a 是一个(复杂/混淆的)常量:to_char('~[gpv:lt]') 并且不是从列派生的
    • @a_horse_with_no_name 正如我在对问题的评论中提到的那样,~[gpv:lt] 的东西是一个 powerschool 标签。它将扩展在 HTTP POST 或 GET 中发送的 lt 参数的值。您在这里看到的内容基本上相当于一个 PHP 页面的片段,其中包含一个带有$_POST["lt"] 的 SQL 查询。除了 powerschool 标记语言比 PHP 可怕得多。 (注意:我不是 PHP 爱好者!)
    • 所以您是说您希望我们看到的 SQL 查询是经过预处理的,并且问题中的 SQL 不是正在处理的 真实 SQL发送到数据库,因为~[gpv:lt] 被替换之前 SQL 被执行?
    • 是的,这个问题的发布者可以通过提及更多上下文来更清楚地说明......看看他以前的问题(显然与同一个查询有关)这是一个持续存在的问题。他似乎不知道“powerschool 的东西”在哪里结束,“oracle 的东西”从哪里开始。但我试图在我的回答中忽略这一点,并专注于所有百分比和逗号的原因
    • 是的,考虑到 ~[gpv:lt] 在 ~[tlist_sql; 中,这有点令人困惑。 ,并且我假设其中的所有内容都是 oracle 查询的一部分。我以前没有学过 SQL/Oracle 或 HTML/CSS/Javascript,所以我缺乏完全理解将是缺乏上下文的原因,所以我道歉。我感谢你们花时间解释它。我会试着剖析你们俩写的所有东西。
    【解决方案3】:

    那些-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”的列通常不包含这样的“结构化数据”。

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

    其他条件做类似的事情。

    【讨论】:

    • 比我快 5 分钟...还是发布了我的
    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2010-12-28
    • 2011-04-16
    • 2010-09-25
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多