1

我有这样的声明:

myuser.orders.exists?(['(orderstatus = ?) ', statusid])

它返回 true,因为有一个与 statusid 匹配的 orderstatus。

接下来我有:

myuser.orders.where('id not in (?)', nil).exists?(['(orderstatus = ?) ', statusid])

这在我认为它可能返回 true 的地方返回 false,因为没有 id 为 nil。

然后我有:

myuser.orders.where(nil).exists?(['(orderstatus = ?) ', statusid])

这返回真。

我的问题是为什么中间语句返回错误?它不会抱怨或抛出任何错误。我想我使用 nil 错误,但有人可以解释一下吗?

4

1 回答 1

4

您遇到了 SQL 的 NULL 问题。where中间那个:

where('id not in (?)', nil)

变成这个 SQL:

id not in (null)

这相当于:

id != null

但结果id != null既非真非假,结果为 NULL 且布尔上下文中的 NULL 为假;事实上,x = nullx != null导致所有人都为 NULL x(即使x它本身为 NULL);例如,在 PostgreSQL 中:

=> select coalesce((11 = null)::text, '-NULL-');
 coalesce 
----------
 -NULL-
(1 row)

=> select coalesce((11 != null)::text, '-NULL-');
 coalesce 
----------
 -NULL-
(1 row)

=> select coalesce((null = null)::text, '-NULL-');
 coalesce 
----------
 -NULL-
(1 row)

=> select coalesce((null != null)::text, '-NULL-');
 coalesce 
----------
 -NULL-
(1 row)

MySQL 和所有其他合理兼容的数据库将做同样的事情(可能有不同的转换要求以使 NULL 显而易见)。

结果是where(id not in (?)', nil)总是产生一个空集,并且你的存在检查总是会在空集上失败。

如果你想说“所有id不为 NULL 的行”,那么你想说:

where('id is not null')

如果你id是主键(几乎可以肯定是),那么id永远不会是 NULL,你可以where完全忽略它。


当你只手where一个nil

where(nil)

where的参数解析逻辑将nil完全忽略 并且where(nil)将与查询相同where()并且where()根本不执行任何操作。结果是就数据库而言,第一个和第三个查询是相同的。

于 2012-05-16T01:33:14.563 回答