2013-07-22 5 views
4

테이블과 필드의 이름을 짧고 이해하기 쉽게 변경했습니다.isNull()을 사용하여 SQLServer update 문이 null 값으로 질식합니다.

나는, 아래 삶은 쿼리가이 오는 :

update destTable 
set destField = (select top 1 isnull(s.sourceField, '') from sourceTable s 
where <various matches between the destTable table and the s table> 
); 

(I 구문 알고 있어요 'destTable d를, sourceTable s의 destTable이 destField를 세트 업데이트 ...' 그러나에 "상위 1"을 넣어하는 방법을 잘 모르겠습니다)이에서

은 내가 SQLServer에 2012 익스프레스 결과를 얻을 :. 모든 필드-NOT NULL로 정의되는 두 테이블의

Msg 515, Level 16, State 2, Line 1 
Cannot insert the value NULL into column 'destField', table 'destTable'; column does not allow nulls. UPDATE fails. 
The statement has been terminated. 

을 및 기본값 ('').

sourceTable이 "where"절에 대해 여러 일치를 가질 수 있으므로 "상위 1"이 중요합니다.

sourceTable의 모든 행을 쿼리했을 때 모든 sourceField 값이 null이 아닌 것으로 나타났습니다. 그러나 나는 결과를 얻는다.

질의의 성격에 따라 1000 개의 destTable 레코드 중 sourceTable과의 일치가 300 개의 행에 대해서만 일치합니다. 다른 700 개의 destTable 레코드는 일치하지 않습니다.

저는 SQLServer가 저에게하고있는 일을 이해하지 못합니다. 이 쿼리는 MySQL을 사용하여 마지막으로 실행했을 때 잘 작동합니다.

미리 감사드립니다. 제롬.

답변

7

문제는 쿼리가 모든 행을 반환하지 않는다는 것입니다. . . 따라서 NULL 값을 생성합니다. 서브 쿼리 외부 isNULL() 이동 :

update destTable 
set destField = isnull((select top 1 s.sourceField 
         from sourceTable s 
         where <various matches between the destTable table and the s table> 
         ), ''); 

을 그런데, 일반적으로 내가이 상황에서 coalesce()을 옹호하는 것, 그것은 표준이기 때문이다. 그러나 Aaron Bertrand here에 설명 된 것처럼 두 가지 동작이 다르게 작동합니다. 특히 첫 번째 인수는 두 번 평가되는 것으로 보이는데 이는 서브 쿼리 일 때 상당히 비쌉니다. 분명히 Isnull()에는이 문제가 없습니다.

+0

내 문제가 해결되었다고 말한 곳에서 isNull()을 둡니다. 매우 감사합니다. –