Rob*_*ert 30 postgresql activerecord ruby-on-rails arel ruby-on-rails-3
我有一个大约100个用户的表,我也有一个用户ID数组.我想要做的是显示所有不属于此用户ID数组的用户.当我做这样的事情
User.where('id NOT IN (?)', [9, 2, 3, 4])
Run Code Online (Sandbox Code Playgroud)
它成功返回用户id不属于该数组的记录.但是,如果该数组是空的,那么
User.where('id NOT IN (?)', [])
Run Code Online (Sandbox Code Playgroud)
它不会返回任何用户,SQL查询看起来像这样
SELECT "users".* FROM "users" WHERE (id NOT IN (NULL))
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会发生这种情况或者这可能是一个错误?我正在使用Rails 3.2.5和PostgreSQL.
Gui*_*iGS 31
在Rails 4中,您可以使用User.where.not(id: [])它来获得正确的结果.它产生:
SELECT "users".* FROM "users" WHERE (1 = 1)
Run Code Online (Sandbox Code Playgroud)
不幸的是User.where('id NOT IN (?)', [])应该是等价的,但事实并非如此 它仍然会给你错误的结果:
SELECT "users".* FROM "users" WHERE (id NOT IN (NULL))
Run Code Online (Sandbox Code Playgroud)
参考文献:
mu *_*ort 25
ActiveRecord(至少3.2.1)将空数组视为NULL.where呼叫中的占位符由处理sanitize_sql.如果你仔细查看代码,你会来replace_bind_variables:
def replace_bind_variables(statement, values) #:nodoc:
raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
bound = values.dup
c = connection
statement.gsub('?') { quote_bound_value(bound.shift, c) }
end
Run Code Online (Sandbox Code Playgroud)
def quote_bound_value(value, c = connection) #:nodoc:
if value.respond_to?(:map) && !value.acts_like?(:string)
if value.respond_to?(:empty?) && value.empty?
c.quote(nil)
else
value.map { |v| c.quote(v) }.join(',')
end
else
c.quote(value)
end
end
Run Code Online (Sandbox Code Playgroud)
一个空数组将满足所有四个条件,c.quote(nil)以及你的NULL来自哪里.所有导致的特殊逻辑c.quote(nil)表明这是故意行为.
用空列表说IN(或NOT IN):
where c in ()
Run Code Online (Sandbox Code Playgroud)
应该产生一个SQL错误,所以也许AR人们试图通过悄悄地将那个糟糕的SQL转变为阻止它c in (null).请注意,这些都不是:
select ... from t where c in (null);
select ... from t where c not in (null);
Run Code Online (Sandbox Code Playgroud)
应该由于SQL的NULL行为而产生任何结果.这是一个经典的新手错误,AR人真的应该知道更好.
我自己更喜欢一个例外:告诉我,我即将部署一个脚踩子弹会比给我一把不同的枪更友好.
执行摘要:
where('c in (?)', []),where('c not in (?)', [])因为这两种说法都没有多大意义.小智 6
User.where('id NOT IN (?)', ids+[0])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7752 次 |
| 最近记录: |