2012-05-16 7 views
1

나는이 문장이 다음 statusid 일치하는 orderstatus 있기 때문에이 ActiveRecord 'where'절은 어떻게 작동합니까?

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

그것은 true를 돌려줍니다.

다음으로 내가 가진이 내가 전무 더 식별자가 없기 때문에 그것이 사실 반환 할 수 있습니다 생각 경우는 false를 돌려줍니다

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

.

그럼 내가 가진이가 true를 돌려

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

.

제 질문은 왜 중간 문이 false를 반환합니까? 불평이나 오류는 발생하지 않습니다. 내가 잘못 사용하는 것 같아요,하지만 누군가 설명 할 수 있을까요?

+0

두 번째 명령문에서 생성 된 쿼리를 로그에서 확인하십시오. 질문에 대한 설명을 제공하지 않는다면 여기에 게시하십시오. –

답변

4

SQL의 NULL에 문제가 있습니다. 중간 하나의 where :

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

이 SQL된다 :

id not in (null) 

하고이 동등의 :

id != null 

그러나 id != null의 결과는 참도 거짓도 아니다는 결과는 NULL이고 부울 컨텍스트에서 NULL은 거짓입니다. 사실 x = nullx != null은 모두 x에 대해 NULL이됩니다 (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)은 항상 빈 세트를 생성하며 사용자의 존재 확인은 항상 빈 세트에서 실패합니다.

where('id is not null') 

당신의 id 기본 키 인 경우 (거의 확실처럼), 다음 id 것 "id이 NULL이 아닌 경우 모든 행을"당신이 말하고 싶은 경우

는 당신이하고 싶은 말 절대 NULL이 아니어야하고 where을 완전히 그대로 둘 수 있습니다.


당신이 단지는 nilwhere 손 :

where(nil) 

where의 인수를 구문 분석 논리가 무시됩니다 nil 완전히 where(nil)where() 같은되며 where() 쿼리에 전혀 아무것도하지 않는다 . 결과적으로 첫 번째와 세 번째 쿼리는 데이터베이스와 관련이 있습니다.

+0

감사합니다.이 말이 맞습니다. 그것을 분명히 설명해 주셔서 감사합니다. – dtc

관련 문제