1

以下のストアド プロシージャは正常に動作しますが、「where」句の日付チェックの 2 番目の部分のコメントを外すと、渡されたキーワードが null または「111」であっても日付変換で爆発するという事実を除きます。

この動的な where 句を別の方法で行う方法についての提案をお待ちしています。

助けていただければ幸いです。

 ALTER PROCEDURE [SurveyEngine].[GetPageOf_CommentsOverviewRowModel]
        @sortColumn varchar(50),
        @isASC bit,
        @keyword varchar(50)
    AS
    BEGIN

        declare @keywordType varchar(4)
        set @keywordType = null

        if ISDATE(@keyword) = 1
            set @keywordType = 'date'
        else if ISNUMERIC(@keyword) = 1
            set @keywordType = 'int'

        select      c.CommentBatch BatchID, c.CreatedDate DateReturned, COUNT(c.CommentID) TotalComments
        from        SurveyEngine.Comment c 
        where       (@keywordType is null)
        or          (@keywordType = 'date') --and c.CreatedDate = @keyword)
        or          (@keywordType = 'int' and (CONVERT(varchar(10), c.CommentBatch) like  @keyword+'%'))

        group by    c.CommentBatch, c.CreatedDate
        order by    case when @sortColumn = 'BatchID' and @isASC = 0 then c.CommentBatch end desc,
                    case when @sortColumn = 'BatchID' and @isASC = 1 then c.CommentBatch end,
                    case when @sortColumn = 'DateReturned' and @isASC = 0 then c.CreatedDate end desc,
                    case when @sortColumn = 'DateReturned' and @isASC = 1 then c.CreatedDate end,
                    case when @sortColumn = 'TotalComments' and @isASC = 0 then COUNT(c.CommentID) end desc,
                    case when @sortColumn = 'TotalComments' and @isASC = 1 then COUNT(c.CommentID) end
    END
4

2 に答える 2

2

EDIT申し訳ありませんが、脳の雲。物事は異なる方法で初期化する必要があります。

セットアップを次のように変更します。

    declare @keywordType varchar(4)
    declare @TargetDate as DateTime = NULL

    set @keywordType = null 

    if ISDATE(@keyword) = 1
        begin
        set @keywordType = 'date'
        set @TargetDate = Cast( @keyword as DateTime )
        end
    else if ISNUMERIC(@keyword) = 1 
        set @keywordType = 'int' 

次に変更します。

and c.CreatedDate = @keyword

に:

and c.CreatedDate = Coalesce( @TargetDate, c.CreatedDate )

日付で検索していない場合は、NOP になります。

于 2012-05-11T01:04:37.323 に答える
2

この男のブログに基づく: http://blogs.msdn.com/b/bartd/archive/2011/03/03/don-t-depend-on-expression-short-circuiting-in-t-sql-not- even-with-case.aspxショート サーキットがサポートされていても、where 句での操作の順序を保証できないようです。実行計画では、2 番目のステートメントを最初に評価することを選択できます。

彼は、代わりに (前に述べた pst のような) ケース構造を使用することをお勧めします。しかし、3 つの異なる演算子 (is null、=、および LIKE) を使用しているため、where 句をケースとして書き直すことはできないと思います。

于 2012-05-11T00:13:06.423 に答える