2013-03-27 2 views
0

이 방법은 간단해야하지만 문제가 계속 발생한다고 생각합니다. 날짜 범위 사이에있는 테이블의 모든 데이터를 반환하기 만하면됩니다. 하지만 기간을 선택 사항으로 지정하고 싶습니다.SQL Server에서 선택적 날짜 매개 변수를 전달하는 방법

ALTER PROCEDURE [dbo].[sp_ExistingPlacements_Get] 
    @DateFrom DATE = NULL, 
    @DateTo DATE = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    SELECT * 
    FROM tblExistingPlacements 
    WHERE 
     CreatedDT > COALESCE(NULLIF(@DateFrom, ''), @DateFrom) 
     AND 
     CreatedDT < COALESCE(NULLIF(@DateTo, GETDATE()), @DateTo) 
END 

따라서 날짜가 전달되지 않으면 우리는 전체 테이블을 반환합니다.

시작 날짜 (DateFrom) 만 전달되면 시작 날짜와 현재 날짜까지의 행을 반환합니다.

에만 종료 날짜 (DateTo는) 다음 전달 된 모든 행 < 반환되는 경우 종료 날짜

그리고 두 날짜가 전달되는 경우 물론, 그 날짜 inbetween 모든 행을 반환합니다.

내가 COALESCE와 (과) 잘못된 경로로 가고 있습니까?

답변

3

하지 마십시오. SQL은 실행 계획 중 하나를 상황에서 작성해야합니다. 그것이 소리만큼 unituitive, 별도의 세 가지 질문이하는 것이 좋습니다 :

ALTER PROCEDURE [dbo].[sp_ExistingPlacements_Get] 
    @DateFrom DATE = NULL, 
    @DateTo DATE = NULL 
AS 
BEGIN 
    SET NOCOUNT ON; 
    IF (@DateFrom IS NULL and @DateTo IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT < GETUTCDATE(); 
    ELSE IF (@DateFrom IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT < @dateTo; 
    ELSE IF (@DateTo IS NULL) 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT BETWEEN @DateFrom AND GETUTCDATE(); 
    ELSE 
     SELECT field, field, field 
     FROM tblExistingPlacements 
     WHERE CreatedDT BETWEEN @DateFrom AND @DateTo; 
END 

매개 변수가 지정되지 않은 전체 테이블을 반환하는 지혜가 매우 의심하지만, 그 시점이 아니다. 게다가 :

  • 쿼리에서 *을 사용하지 않습니다, 항상 명시 적으로
  • 항상 Dynamic Search Conditions in T-SQL 볼이 주제에 대한 철저한 설명은 데이터베이스

에서 UTC 시간을 사용하는 투사 목록을 지정합니다.

+0

Remus 감사합니다. 예 - 저는 실제로 *를 사용하지 않았지만 이것은 제 문제를 쉽게 설명하기위한 것입니다. – wotney

6

사용 ISNULL(@parameter) OR (--your condition--) 대신 COALESCE :

매개 변수가 ISNULL 반환 TRUE를 제공하지, 그래서 OR의 두 번째 부분은 문제가되지 않을 경우
BEGIN 
    SET NOCOUNT ON; 
    SELECT * 
    FROM tblExistingPlacements 
    WHERE 
     ((@DateFrom IS NULL) OR CreatedDT > @DateFrom) 
     AND 
     ((@DateTo IS NULL) OR CreatedDT < @DateTo) 
END 

.

+0

고마워 Marcin, "ISNULL 함수에 2 개의 인수가 필요합니다." – wotney

+0

@wotney 내 대답이 업데이트되었습니다. 지금 확인해주세요. – MarcinJuraszek

+0

환상적 - 감사합니다. – wotney

관련 문제