뷰 열을 NULL이 아닌 것으로 만드는 방법


84

열이 참 또는 거짓이되기를 원하는 뷰를 만들려고합니다. 그러나 내가 무엇을하든 SQL Server (2008)는 내 비트 열이 어떻게 든 널이 될 수 있다고 생각합니다.

"상태"열이있는 "제품"이라는 테이블이 INT, NULL있습니다. 뷰에서 Product.Status 열이 3이면 BIT 열을 true로 설정하여 Product의 각 행에 대해 행을 반환하고, 그렇지 않으면 비트 필드가 false 여야합니다.

SQL 예

SELECT CAST( CASE ISNULL(Status, 0)  
               WHEN 3 THEN 1  
               ELSE 0  
             END AS bit) AS HasStatus  
FROM dbo.Product  

이 쿼리를 뷰로 저장하고 개체 탐색기에서 열을 보면 HasStatus 열이로 설정됩니다 BIT, NULL. 그러나 NULL이 아니어야합니다. 내가 할이 열을 강제하는 데 사용할 수있는 몇 가지 마법의 SQL 트릭이 있습니까 NOT NULL.

CAST()주변을 제거하면 CASE열이로 올바르게 설정 NOT NULL되지만 열의 유형이로 설정되어 INT원하는 것이 아닙니다. 나는 그것을 원한다 BIT. :-)

답변:


150

쿼리를 약간 다시 정렬하여 원하는 것을 얻을 수 있습니다. 비결은 ISNULLSQL Server가 결과 값이 결코 될 수 없다는 것을 이해하기 전에 외부에 있어야한다는 것 NULL입니다.

SELECT ISNULL(CAST(
    CASE Status
        WHEN 3 THEN 1  
        ELSE 0  
    END AS bit), 0) AS HasStatus  
FROM dbo.Product  

실제로 이것이 유용하다고 생각하는 한 가지 이유는 ORM을 사용할 때 결과 값을 nullable 형식에 매핑하지 않기 때문입니다. 응용 프로그램에서 값이 절대로 null이 아닌 것으로 간주하면 모든 것을 쉽게 할 수 있습니다. 그러면 널 예외 등을 처리하기 위해 코드를 작성할 필요가 없습니다.


@ 건더 : 걱정하지 마세요. 사실 조금 신비 롭습니다. 테이블에 계산 된 비트 열을 생성하고 결과가 null을 허용하지 않도록하려는 경우에도 편리합니다.
RedFilter 2010

8
나는 비슷한이 필요하고, 그 발견 COALESCE(), 당신은 실제로 작동하지 않았다 해야 사용ISNULL()
EvilBob22

@ EvilBob22 COALESCE와 ISNULL이 모두 NULL을 반환 할 수 있기 때문에 이상합니다. 내가 생각하기에 컴파일러의 별난 것입니다.
RedFilter

1
이것은 일반적으로 추론되지 않을 때 EntityFramework가 키를 추론하도록하기 위해 10 억 배입니다.
Erik


3

참고로이 메시지를 실행하는 사람들의 경우 캐스트 / 변환 외부에 ISNULL ()을 추가하면 뷰의 최적화 프로그램이 엉망이 될 수 있습니다.

인덱스 키와 동일한 값을 사용하지만 숫자 정밀도 유형이 다른 테이블이 2 개 있었으며 (나쁜, 알다시피) 뷰는 최종 결과를 생성하기 위해 결합했습니다. 그러나 미들웨어 코드는 특정 데이터 유형을 찾고 있었고 뷰에는 반환 된 열 주위에 CONVERT ()가 있습니다.

OP와 마찬가지로 뷰 결과의 열 설명자가 nullable로 정의했으며 2 개의 테이블에서 기본 / 외래 키라고 생각했습니다. 결과가 nullable로 정의되기를 원하는 이유는 무엇입니까?

이 게시물을 발견하고 열과 짜잔 주위에 ISNULL ()을 던졌습니다-더 이상 nullable이 아닙니다.

문제는 쿼리가 해당 열에서 필터링 될 때 뷰의 성능이 바로 변기 아래로 내려 갔다는 것입니다.

어떤 이유로 뷰의 결과 열에 대한 명시 적 CONVERT ()는 최적화 프로그램을 망가 뜨리지 않았지만 (정밀도가 다르기 때문에 어쨌든 그렇게해야했습니다) 중복 ISNULL () 래퍼를 추가하면 큰 문제가 발생했습니다. 방법.


CONVERT()예를 들어 Null 가능성을 보장 / 표시하는 방법에 대한 솔루션을 보여줄 수 있습니까?
OR Mapper

1
안녕하세요 OR-잠시 동안 보지 못해서 죄송합니다. 여기에 예가 있습니다. 뷰에서 CONVERT (BIT, U.RETIRED), 0) AS Retired가있는 경우 바이트 또는 int 열을 비트 / 불로 바꾸면 nullable이됩니다. 뷰의 해당 열을 ISNULL (CONVERT (BIT, U.RETIRED), 0) AS Retired로 대체하여 Null을 허용하지 않도록 할 수 있습니다. U.RETIRED가 시작하기 위해 null이 아닌 경우 뷰의 열을 제외하고는 기능적으로 아무것도 변경하지 않습니다. 경고 : ISNULL ()은 쿼리 최적화 및 인덱스 선택을 방해 할 수 있습니다.
user1664043

-3

Select 문에서 할 수있는 일은 데이터베이스 엔진이 클라이언트로 보내는 데이터를 제어하는 ​​것뿐입니다. select 문은 기본 테이블의 구조에 영향을주지 않습니다. 테이블 구조를 수정하려면 Alter Table 문을 실행해야합니다.

  1. 먼저 테이블의 해당 비트 필드에 현재 null이 없는지 확인하십시오.
  2. 그런 다음 다음 ddl 문을 실행합니다. Alter Table dbo.Product Alter column status bit not null

otoh, 당신이하려는 모든 것이 뷰의 출력을 제어하는 ​​것이라면, 당신이하는 일은 충분합니다. 귀하의 구문은 뷰의 결과 집합에서 HasStatus 컬럼의 출력이 실제로 것이라는 점을 보장 할 것이다 결코 null 일 수 없습니다. 그것은 것입니다 항상 음주 개체 탐색기의 말씀 걱정 중 하나 비트 값 = 1 비트 값 = 0이 ...


6
테이블 열을 변경하고 싶지 않습니다. 열은 널을 허용하는 정수 열로 정의됩니다. 이것은 우리의 사양에 맞습니다. 하지만 null 일 수없는 비트 필드가있는 열을 반환하는 뷰가 필요합니다. 널이 될 수 없다는 것을 아는 것만으로는 충분하지 않으며, 열은 NULL이 아니어야 ORM에서 올바르게 매핑됩니다.
René
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.