我在本地运行MySQL数据库进行开发,但部署到使用Postgres的Heroku.Heroku几乎可以处理所有事情,但是我的不区分大小写的Like语句变得区分大小写.我可以使用iLike语句,但我的本地MySQL数据库无法处理.
编写与MySQL和Postgres兼容的不区分大小写的查询的最佳方法是什么?或者我是否需要根据我的应用正在与之交谈的数据库编写单独的Like和iLike语句?
这个故事的寓意是:不要使用不同的软件堆栈进行开发和生产.决不.
你最终会得到你无法在开发中重现的错误; 你的测试将毫无价值.只是不要这样做.
使用不同的数据库引擎是不可能的 - 会有更多的情况,它的行为与LIKE不同(同样,您是否检查了数据库使用的排序规则?在每种情况下它们是否相同?如果没有,您可以忘记工作相同的varchar列上的ORDER BY)
select * from foo where upper(bar) = upper(?);
如果在调用者中将参数设置为大写,则可以避免第二个函数调用.
使用Arel:
Author.where(Author.arel_table[:name].matches("%foo%"))
matches
将使用ILIKE
Postgres 的运算符,以及LIKE
其他所有内容.
在postgres中,你可以这样做:
SELECT whatever FROM mytable WHERE something ILIKE 'match this';
我不确定是否有相同的MySQL,但你总是这样做有点难看,但应该在MySQL和postgres中工作:
SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this');
有几个答案,其中没有一个非常令人满意.
LOWER(条)= LOWER(?)将工作在MySQL和Postgres,但很可能在MySQL可怕执行:MySQL不会使用,因为较低的功能,它的索引.在Postgres上你可以添加一个功能索引(在LOWER(bar)上),但是MySQL不支持这个.
MySQL将(除非您设置了区分大小写的排序规则)自动执行不区分大小写的匹配,并使用其索引.(bar =?).
从数据库外部的代码中,维护bar和bar_lower字段,其中bar_lower包含lower(bar)的结果.(这也许可以使用数据库触发器).(请参阅关于Drupal的此解决方案的讨论).这很笨拙,但至少在每个数据库上都运行相同的方式.
REGEXP不区分大小写(除非与BINARY一起使用),并且可以使用,如此...
SELECT id FROM person WHERE name REGEXP 'john';
......匹配'John','JOHN','john'等.