【问题标题】:CASE in SELECT WHERE statement for stored procedure?存储过程的 SELECT WHERE 语句中的 CASE?
【发布时间】:2012-01-04 01:41:27
【问题描述】:

我需要在存储过程中根据 ManufacturerID 过滤表,但是当传入 null ManufacturerID 时,我需要所有订单。

我可以在 WHERE 语句中执行此操作,这样我就不必在我的 SP 中将整个查询写入两次了吗?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:
    WHERE
      @param IS NULL OR field = @param
    

    但请注意,如果您将其放大以搜索多个列,这将变得非常低效。 (见http://www.sommarskog.se/dyn-search.html

    低效放大版示例...

    WHERE
          (@param1 IS NULL OR field1 = @param1)
      AND (@param2 IS NULL OR field2 = @param2)
      AND (@param3 IS NULL OR field3 = @param3)
    

    【讨论】:

    • 好奇WHERE ManufacturerID = coalesce(@param,ManufacturerID)
    • @vol7ron - 仅提供 @param 为 NULLABLE 而不是字段本身,则可以。您的版本将永远不会返回 ManufacturerID 为 NULL 的任何记录。除此之外,它的行为与我的答案相同。
    • 只是好奇,有一段时间没有使用 SQL Server - 马克班尼斯特似乎对我的评论有所反应 :) 鉴于你的说法,我会告诉他这样做 WHERE coalesce(table.field,'') = coalesce(@param, table.field, ''),但你的解决方案是显然是最好的选择
    • @vol7ron - 假设'' 已经不是表中的合法值。另外,请注意隐式转换;在这种情况下,该字段可能是 INT 而不是字符串。
    【解决方案2】:

    你可以这样做:

    where t.ManufacturerID = @ManufacturerIDParam OR @ManufacturerIDParam is null
    

    【讨论】:

    • @Downvoters 鉴于此答案与已接受的答案几乎相同,您愿意解释一下您的投票吗?
    • +1 - 面对不公正,直到反对票被解释或删除
    【解决方案3】:

    试试:

    WHERE table.field = coalesce(@param, table.field)
    

    【讨论】:

    • 不太可能,因为 OP 提到了一个 ID 字段,但这确实有一个需要注意的角落案例:这将永远不会返回 field IS NULL 的记录
    【解决方案4】:

    这也可能导致参数嗅探问题。如果可能,是否希望先清理空值?

    【讨论】:

    • 这没有抓住重点。 OP 正在尝试对数据编写通用过滤器。如果指定了值,则只返回匹配的记录。否则,如果没有指定值,则返回所有记录。
    猜你喜欢
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多