【问题标题】:How To find Exact string match within a String in Oracle如何在Oracle中的字符串中找到精确的字符串匹配
【发布时间】:2011-05-05 09:46:55
【问题描述】:

我有一个 oracle 表,其中有一个名为 system_access 的列,其中包含以下数据:

Read Only, Write, read only, Admin
Read, Write, read only, Admin
Admin, Read Only (no), read only(see mgr), Admin

根据上述示例数据,我不确定我的查询是否仅检索与“只读”和/或“只读”的确切单词匹配的记录

我不需要具有“只读(无)”和空格的记录,然后在它之后或之前加上括号,或者在它之后或之前没有空格和括号的“只读(见经理)”。

所以基于上面的示例数据,我只会返回两行,即:

Read Only, Write, read only, Admin
Read, Write, read only, Admin

如前所述,仅记录与字符串“只读”或“只读”完全匹配的记录

【问题讨论】:

  • 这对我来说绝对是一个概念错误。您正在打破第一个正常形式(en.wikipedia.org/wiki/First_normal_form),这完全是非进化的。如果可能,我强烈建议您修改当前的设计。
  • @Vincent Savard,完全同意你的观点,但不幸的是继承了这个设计错误,目前没有更正设计的范围。

标签: sql oracle plsql oracle10g


【解决方案1】:

从表中选择 * 其中 lower(trim(column_name)) = '只读'

【讨论】:

  • 我想你漏掉了,这个专栏里不仅有一条数据,还有多个“Read Only, Write, read only, Admin”
【解决方案2】:

试试

SELECT *
  FROM TABLE
  WHERE REGEXP_LIKE(system_access, '[^()]. read only. [^()],', 'i') OR
        REGEXP_LIKE(system_access, '[^()]. read only. [^()]$', 'i');

我认为这适用于显示的数据,但为时已晚,我远非正则表达式专家,而且我手边没有文档。

分享和享受。

【讨论】:

    【解决方案3】:

    有时在比较之前向字符串添加一些内容很有用,然后每个元素都遵循相同的格式:

    with testData as
    (
      select 'Read Only, Write, read only, Admin' test from dual union all
      select 'Read, Write, read only, Admin'  test from dual union all
      select 'Admin, Read Only (no), read only(see mgr), Admin' test from dual
    )
    select * from testData
    where lower(test)||',' like '%read only,%';
    

    【讨论】:

      【解决方案4】:
      select * from table where lower(system_access) like '%read only,%';
      

      只要表格数据不变,这将起作用。使用正则表达式也可以,但正则表达式必须再次正确地制作,如果数据发生变化,这一切都是徒劳的。

      【讨论】:

      • 如果“只读”恰好在列表的末尾,这将不起作用。
      • ...尽管如果将lower(system_access) 更改为lower(system_access) || ',' 则会这样做。
      • 是的,但是问题中包含了完整的表格内容,这就是为什么我用“只要表格数据不改变”来澄清我的答案
      【解决方案5】:

      @jonearles answer 中的搜索 "%read only,%" 方法可以正常工作。但是,由于您已经被明显疯狂的底层设计所困扰,在权限测试中增加一点严格性可能是合适的。

      我很想假设您总是有一个逗号分隔的字符串,并且在进行权限测试时解析文本并检查特定条目“只读”和“只读”。

      您还可以通过检查已解析的权限字符串中的每个令牌与包含已知角色集的表(即“只读”、“只读(参见经理)”)来扩展此功能。该表甚至可以包含一个与您的您可以在查询中使用的“只读”定义相匹配的标志。

      【讨论】:

        【解决方案6】:

        接受@Bob Jarvis(虽然我不能 t 让他使用下面的数据样本)更进一步并放弃 OR

        WITH DATA AS(
        SELECT '1- Read Only, Write, read only, Admin' SYSTEM_ACCESS FROM DUAL UNION
        SELECT '2- Write, Admin,Read Only' SYSTEM_ACCESS FROM DUAL UNION
        SELECT '3- Read, Write, read only, Admin' SYSTEM_ACCESS FROM DUAL UNION
        select '4- ADMIN, READ ONLY (NO), READ ONLY(SEE MGR), ADMIN' system_access from dual 
        )
        select * 
          FROM DATA
         WHERE REGEXP_LIKE(SYSTEM_ACCESS, '(read only[ ,]+[^/(])|(read only$)','i');
        

        REGEXP_LIKE(SYSTEM_ACCESS, '(只读[ ,]+[^/(])|(只读$)','i'); 这将查找后面可能有空格或逗号但禁止打开 ( 或字符串末尾的“只读”) 的所有“只读”实例。

        (http://www.regular-expressions.info/oracle.html & http://psoug.org/snippet.htm/Regular_Expressions_Regex_Cheat_Sheet_856.htm?PHPSESSID=7238be874ab99d0731a9da64f2dbafd8)

        【讨论】:

        • 我认为你是对的,这两个正则表达式可以用“|”组合它们之间。正如我所说,我远非正则表达式大师...... :-)
        • @BobJarvis,我也不是!我试图找到每天使用它的理由只是为了更流畅地使用它,这是我真正开始喜欢查找和替换的事情之一
        猜你喜欢
        • 1970-01-01
        • 2017-10-28
        • 2023-01-09
        • 2022-11-26
        • 1970-01-01
        • 2021-10-18
        相关资源
        最近更新 更多