【问题标题】:Case insensitive search without using a function in the where clause不使用 where 子句中的函数的不区分大小写的搜索
【发布时间】:2019-01-22 00:26:13
【问题描述】:

有什么方法可以在不使用 where 子句中的函数的情况下不区分大小写?
请指定您在回复时/如果您正在谈论的数据库。我知道 MySQL 默认情况下已经不区分大小写。 Oracle、MSSQL 或 HANA 呢?

select * from mytable WHERE upper(fieldname) = 'VALUE'

【问题讨论】:

  • 如果您的目标数据库(您从未告诉我们您实际使用的是哪个数据库)不支持这种行为,您可以随时维护一个单独的列,其中包含不区分大小写的原始列版本。
  • 嗯,对于每个 rdbms,它是不同的 - 在 Wanderer 的答案中使用 collate 行是针对 SQL Server,使用 SET NLS_COMP 是针对 Oracle,而对于 Sap Hana,这可能是完全不同的事情。
  • upper(columnname) = 'VALUE' 几乎可以与任何 dbms 一起使用。但是,不要期望总是使用索引,所以性能可能真的很差。
  • 我认为关于 4 个数据库的问题太宽泛了。
  • 同意@GordonLinoff 的观点,这个问题似乎过于宽泛,无法得出一个最佳答案。此外,问题背后的重要动机似乎是解决方案仍应允许 RDBMS 使用索引。那应该是问题的一部分。

标签: sql sql-server oracle hana case-sensitive


【解决方案1】:

collate SQL_Latin1_General_CP1_CS_AS

默认排序规则是 SQL_Latin1_General_CP1_CI_AS,即 case insensitive。如果我们需要让它区分大小写,那么添加 COLLATE Latin1_General_CS_AS 会使搜索区分大小写。

查询

select * from [mytable] 
where [fieldname] = 'VALUE' collate SQL_Latin1_General_CP1_CS_AS;

Find a demo here

【讨论】:

  • 这适用于 MS SQL Server、Hana 还是 Oracle?
  • @jarlh : MS SQL Server
  • 我正在寻找如何在 mssql、oracle 和 hana 中执行此操作。我想了解如何。
【解决方案2】:

由于您的问题被标记为 Oracle,我将提供适用于 Oracle 的解决方案。

您可以为不区分大小写的搜索设置这些会话参数

SQL> alter session set NLS_COMP=ANSI;
SQL> alter session set NLS_SORT=BINARY_CI; 
SQL> select 1 from DUAL where 'abc' = 'ABC';

         1
----------
         1

阅读更多Linguistic Sorting and String Searching

正如@mathguy 指出的那样,

ALTER SESSION SET NLS_COMP=LINGUISTIC; 

比使用 ANSI 更常见

【讨论】:

  • 我要补充:_CI 表示“不区分大小写”; NLS_COMP 也必须(重新)设置,默认为 BINARY,它应该重置为 LINGUISTIC(ANSI 也可以,但 LINGUISTIC 更常见)。此外,作为一种风格,最好将值括在单引号中,尽管 Oracle 允许 BINARY_CI 等不带引号出现。
【解决方案3】:

为了比较它而使列大写(或小写)是进行不区分大小写比较的标准方法。 (UPPERLOWER 是 SQL 标准中定义的函数。)

如果您不想在列上应用函数,那么您当然可以编写递归查询来生成值的所有大写/小写排列('VALUE'、'vALUE'、'VaLUE'、 ..., 'value') 并检查您的列值是否在此集合中。标准 SQL 提供了 SUBSTRING 函数用于访问子字符串(例如第 n 个字母)和 CHAR_LENGTH 用于获取字符串的长度。

这取决于您使用的 DBMS 及其版本对标准的支持程度。例如,在 Oracle 中,它是 SUBSTR 而不是 SUBSTRINGLENGTH 而不是 CHAR_LENGTH。另一方面,MySQL 直接具有 SUBSTRINGCHAR_LENGTH,但仅支持 8.0 版的递归查询。

【讨论】:

    【解决方案4】:

    这将起作用:

    SELECT *
    FROM mytable
    WHERE REGEXP_LIKE (column_name, 'value', 'i');
    

    【讨论】:

    • 这个查询的问题是你现在有 regexp_like 作为 where 子句中的函数。如果您要查询一个巨大的表,该函数必须在每一行上运行。我的目标是去掉 where 子句中的函数。
    • 但是为什么要去掉where子句中的函数。如果它是一个大表会不会引起任何问题。
    • 在 where 子句中使用函数通常不是一个好主意,因为它会使索引无效。 (除非你也索引了这个函数)。
    • 即使您避免使用 WHERE 子句,更改比较逻辑通常也会导致无法访问索引。例如。在 Oracle 上,更改的 NLS 设置将需要使用这些设置创建的附加索引。参见例如richardfoote.wordpress.com/2008/01/03/…
    【解决方案5】:

    Oracle 12c 答案

    select * from mytable WHERE fieldname='Value' collate binary_ci
    

    SAP HANA除了使用upper或lower似乎没有别的办法。

    SQL Server 和 MySQL 不区分大小写字母——默认情况下它们不区分大小写。

    【讨论】:

      猜你喜欢
      • 2016-09-03
      • 2020-12-06
      • 1970-01-01
      • 2021-02-27
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 1970-01-01
      相关资源
      最近更新 更多