0

これは簡単なことだと思いますが、私は問題にぶつかり続けています。日付範囲の間にあるテーブルからすべてのデータを返したいだけです。しかし、日付範囲はオプションにしたいです。

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)のみが渡された場合は、すべての行を返します<終了日

そしてもちろん、両方の日付が渡された場合は、それらの日付の間のすべての行を返します。

COALESCEで間違ったルートを進んでいますか?

4

2 に答える 2

7

ISNULL(@parameter) OR (--your condition--)の代わりに使用COALESCE

BEGIN
    SET NOCOUNT ON;
    SELECT *
    FROM tblExistingPlacements
    WHERE
      ((@DateFrom IS NULL) OR CreatedDT > @DateFrom)
      AND
      ((@DateTo IS NULL) OR CreatedDT < @DateTo)
END

パラメータが指定されていない場合はISNULLreturnTRUEを返すため、の2番目の部分は重要でORはありません。

于 2013-03-27T11:43:23.393 に答える
3

こんなことしないで。SQLは、どのような状況でも機能する1つの実行プランを作成する必要があります。統一感があるように聞こえますが、次の3つの個別のクエリを使用することをお勧めします。

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

パラメータが指定されていないときにテーブル全体を返すという知恵は非常に疑わしいですが、それは重要ではありません。その上:

  • クエリでは使用*しないでください。常に投影リストを明示的に指定してください
  • データベースでは常にUTC時間を使用します

このトピックの詳細については、T-SQLの動的検索条件を参照してください。

于 2013-03-27T12:12:59.507 に答える