SQL の NULL に問題があります。where
真ん中のもの:
where('id not in (?)', nil)
次の SQL になります。
id not in (null)
そしてそれはこれと同等です:
id != null
しかし、 の結果id != null
は真でも偽でもありません。結果は NULL で、ブール値コンテキストの NULL は偽です。実際、x = null
結果x != 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()
その結果、データベースに関する限り、1 番目と 3 番目のクエリは同じになります。