1

下面的存储过程工作正常,除了当我在“where”子句中取消注释日期检查的第二部分时,即使传入的关键字为空或“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

基于这个家伙的博客: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 子句中的操作顺序,即使支持短路也是如此。执行计划可以选择先评估第二条语句。

他建议改用案例结构(如前面提到的 pst ),因为它“更多”得到保证。但是我不认为我可以将您的 where 子句重写为一个案例,因为您使用了三个不同的运算符(为 null、= 和 LIKE)。

于 2012-05-11T00:13:06.423 回答
2

编辑对不起,脑云。事物需要以不同的方式初始化。

将设置更改为:

    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 回答