64

我在本地运行 MySQL 数据库进行开发,但部署到使用 Postgres 的 Heroku。Heroku 几乎可以处理所有事情,但我不区分大小写的 Like 语句变得区分大小写。我可以使用 iLike 语句,但我的本地 MySQL 数据库无法处理。

编写与 MySQL 和 Postgres 兼容的不区分大小写查询的最佳方法是什么?或者我是否需要根据我的应用程序正在与之交谈的数据库编写单独的 Like 和 iLike 语句?

4

11 回答 11

74

这个故事的寓意是:不要使用不同的软件堆栈进行开发和生产。绝不。

您最终会遇到无法在开发中重现的错误;你的测试将毫无价值。只是不要这样做。

使用不同的数据库引擎是不可能的 - 会有更多的情况下它的行为与 LIKE 不同(另外,您是否检查过数据库使用的排序规则?它们在每种情况下都相同吗?如果不是,你可以忘记在 varchar 列上的 ORDER BY 工作相同)

于 2009-10-11T14:47:06.707 回答
58
select * from foo where upper(bar) = upper(?);

如果在调用者中将参数设置为大写,则可以避免第二次函数调用。

于 2008-10-15T01:16:19.450 回答
36

使用阿雷尔:

Author.where(Author.arel_table[:name].matches("%foo%"))

matches将对ILIKEPostgres 和LIKE其他所有内容使用运算符。

于 2012-04-13T23:15:00.760 回答
13

在 postgres 中,你可以这样做:

SELECT whatever FROM mytable WHERE something ILIKE 'match this';

我不确定是否有 MySQL 的等价物,但你总是可以这样做,这有点难看,但应该在 MySQL 和 postgres 中都可以工作:

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');
于 2008-10-15T01:21:33.170 回答
8

有几个答案,没有一个是非常令人满意的。

  • LOWER(bar) = LOWER(?)将在 MySQL 和 Postgres 上工作,但可能在 MySQL 上执行得非常糟糕:由于 LOWER 函数,MySQL 不会使用它的索引。在 Postgres 上,您可以添加功能索引(在LOWER(bar)上),但 MySQL 不支持此功能。
  • MySQL 将(除非您设置了区分大小写的排序规则)自动进行不区分大小写的匹配,并使用其索引。(酒吧=?)。
  • 从数据库外部的代码中,维护barbar_lower字段,其中 bar_lower 包含lower(bar)的结果。(这也可以使用数据库触发器)。(请参阅Drupal上对此解决方案的讨论)。这很笨拙,但至少在几乎每个数据库上都以相同的方式运行。
于 2012-06-20T12:14:25.847 回答
5

REGEXP 不区分大小写(除非与 BINARY 一起使用),并且可以像这样使用...

    SELECT id FROM person WHERE name REGEXP 'john';

...匹配“John”、“JOHN”、“john”等。

于 2012-07-31T22:30:01.820 回答
2

如果您使用的是 PostgreSQL 8.4,您可以使用citext模块来创建不区分大小写的文本字段。

于 2010-03-05T16:19:33.533 回答
2

使用整理。

http://dev.mysql.com/doc/refman/5.0/en/case-sensitive.html

于 2012-04-27T15:37:46.520 回答
1

您也可以考虑查看searchlogic插件,它为您执行LIKE/ILIKE切换。

于 2009-10-11T14:41:45.797 回答
1

如果要匹配块中的子字符串,也可以在 postgres 中使用 ~*。~ 匹配区分大小写的子字符串,~* 不区分大小写的子字符串。这是一个缓慢的操作,但我可能会发现它对搜索有用。

Select * from table where column ~* 'UnEvEn TeXt';
Select * from table where column ~ 'Uneven text';

两者都会点击“Some Uneven text here” 只有前者会点击“Some UNEVEN TEXT here”

于 2011-01-12T00:59:18.337 回答
0

转换为 upper 是最好的,因为它涵盖了 3 个最常用的 Rails 数据库后端的兼容语法。PostgreSQL、MySQL 和 SQLite 都支持这种语法。它有一个(小)缺点,您必须在应用程序或条件字符串中将搜索字符串大写,这使它有点难看,但我认为您获得的兼容性使其值得。

MySQL 和 SQLite3 都有一个不区分大小写的 LIKE 运算符。只有 PostgreSQL 有一个区分大小写的 LIKE 运算符和一个 PostgreSQL 特定的(根据手册)ILIKE 运算符,用于不区分大小写的搜索。您可以在 Rails 应用程序的条件中指定 ILIKE 而不是 LIKE,但请注意该应用程序将停止在 MySQL 或 SQLite 下工作。

第三种选择可能是检查您正在使用的数据库引擎并相应地修改搜索字符串。这可能通过侵入/monkeypatching ActiveRecord 的连接适配器并让 PostgreSQL 适配器修改查询字符串以在查询执行之前用“LIKE”替换“ILIKE”来更好地完成。然而,这个解决方案是最复杂的,并且考虑到像大写这两个术语这样更简单的方法,我认为这不值得努力(尽管这样做你会得到很多布朗尼点)。

于 2009-03-05T18:19:05.423 回答