【问题标题】:Oracle DB: How can I write query ignoring case?Oracle DB:如何编写忽略大小写的查询?
【发布时间】:2010-11-05 03:13:32
【问题描述】:

正如我在标题中所写,我有 SQL 查询,在 Oracle DB 上运行,可以说:

SELECT * FROM TABLE WHERE TABLE.NAME Like 'IgNoReCaSe'

如果我愿意,查询将返回“IGNORECASE”、“ignorecase”或它们的组合,该怎么做?

【问题讨论】:

标签: sql database oracle


【解决方案1】:

在 12.2 及更高版本中,使查询不区分大小写的最简单方法是:

SELECT * FROM TABLE WHERE TABLE.NAME COLLATE BINARY_CI Like 'IgNoReCaSe'

【讨论】:

    【解决方案2】:

    使用 ALTER SESSION 语句将比较设置为不区分大小写:

    alter session set NLS_COMP=LINGUISTIC;
    alter session set NLS_SORT=BINARY_CI;
    

    如果您仍在使用 10gR2 版本,请使用以下语句。见this FAQ for details

    alter session set NLS_COMP=ANSI;
    alter session set NLS_SORT=BINARY_CI;
    

    【讨论】:

    • 如果 zeroDevisible 在 10gR2 或更高版本上,这比基于函数的索引要好得多,因为它将覆盖查询中的所有 12 个字段,而不会产生所有这些索引的开销。一个潜在的问题是用户每次都需要更改会话。
    • 我不确定你在说什么开销。如果您创建一个“正常”索引,然后更改 NLS_COMP 和 NLS_SORT,Oracle 将无法再使用该索引来查找有问题的数据。因此,您最终会为任何合适的列创建特定于 NLS 设置的索引。对我来说,与基于函数的索引 (FBI) 相比,它如何产生更多或更少的开销对我来说并不明显。显然,如果您希望所有查询不区分大小写,则无需在列上维护索引并在 UPPER(column) 上维护 FBI(或为不同的 NLS 设置维护索引)
    • @devio Dosent 在版本中为我工作:12 c 请更新您的答案
    【解决方案3】:

    您可以使用upperlower 函数将这两个值转换为大写或小写:

    Select * from table where upper(table.name) like upper('IgNoreCaSe')
    

    Select * from table where lower(table.name) like lower('IgNoreCaSe');
    

    【讨论】:

    • 这可能是正确的答案,但请注意,它可能会破坏您对字符串的任何索引。如果您需要索引,您可能需要添加一个新列,您始终在其中插入大小写标准化值。
    • 为什么是or?是否可以大写匹配小写不匹配?
    • 我认为@user3666177 发布了or 来演示这两个选项。我不认为一个匹配而另一个匹配是不可能的。
    【解决方案4】:

    你也可以使用正则表达式:

    SELECT * FROM TABLE WHERE REGEXP_LIKE (TABLE.NAME,'IgNoReCaSe','i');
    

    【讨论】:

      【解决方案5】:

      您可以在查询中使用 upper() 函数,为了提高性能,您可以使用基于函数的索引

       CREATE INDEX upper_index_name ON table(upper(name))
      

      【讨论】:

      • 好建议!您能否提供一个如何使用索引执行搜索的示例?
      【解决方案6】:

      也不要忘记显而易见的,表中的数据需要有大小写吗?您只能插入已经小写的行(或将现有的数据库行转换为小写)并从一开始就完成。

      【讨论】:

      • 如果你有专有名词,这是一个问题。特别是如果您在同一领域中同时使用专有名词和非专有名词。
      【解决方案7】:

      ...也在查询之外进行转换为上限或下限:

      tableName:= UPPER(someValue || '%');
      

      ...

      Select * from table where upper(table.name) like tableName 
      

      【讨论】:

        【解决方案8】:
        Select * from table where upper(table.name) like upper('IgNoreCaSe');
        

        或者,用lower代替upper。

        【讨论】:

        • 我会小心LIKE。这可能会导致不必要的副作用,例如当字符串包含像% 这样的特殊字符时。使用upper(table.name) = upper('iGnOrEcASe') 应该更安全。
        【解决方案9】:

        你可以在 where 条件的两边使用 lower 或 upper 函数

        【讨论】:

        • 感谢您这么快的答复。我想知道,因为我的查询从非常大的表中选择了大约 12 个字段,所以我需要大约 20 次使用上层函数 - 这不会影响性能吗?
        • 如果您知道要检查的确切单词,您可以使用 IN 语句 (SELECT * FROM TABLE WHERE UPPER(NAME) IN (UPPER('Name1'), UPPER('Name2' )); 或者如果名称都以相同的开头,您可以使用通配符 (SELECT * FROM TABLE WHERE UPPER(NAME) LIKE UPPER('Search%');)
        • 如果您谈论的是 Oracle 执行操作所花费的时间,那么使用像 upper 这样的函数永远不会影响性能 - 与 cpu 进行转换所花费的时间相比,从缓存加载数据页所花费的时间,更不用说从磁盘中获取它了。但是,使用 lower 或 upper 将阻止您的查询使用这些列上的任何索引,除非您创建了使用这些函数的索引。但 LIKE 也可能会阻止索引的使用,尤其是当表达式中的第一个字符是通配符时。
        猜你喜欢
        • 1970-01-01
        • 2012-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-25
        • 2011-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多