1

私はこの声明を持っています:

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

statusid に一致する orderstatus があるため、true を返します。

次に私が持っている:

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

これは、nil の ID がないため、true を返す可能性があると思っていたところに false を返します。

で、〜がある:

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

これは true を返します。

私の質問は、中央のステートメントが false を返すのはなぜですか? 文句を言ったり、エラーをスローしたりしません。私は 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 = 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が主キーである場合(ほぼ確実にそうです)、idNULLになることはなく、where完全に省略できます。


whereだけを渡す場合nil:

where(nil)

wherenilの引数解析ロジックは を完全に無視し、where(nil)と同じになり、クエリに対して何もしませんwhere()where()その結果、データベースに関する限り、1 番目と 3 番目のクエリは同じになります。

于 2012-05-16T01:33:14.563 に答える