【问题标题】:Select all if parameter is null in stored procedure如果存储过程中的参数为空,则全选
【发布时间】:2011-11-22 18:12:58
【问题描述】:

我想在 SQL Server 中创建一个用于选择和连接两个表的过程。参数@company、@from 和@to 始终设置,但@serie_type 可以为NULL。如果@serie_type 不为NULL,我只想包含指定的类型,简单AND S.Type = @serie_type,但如果@serie_type 为NULL,我想包含所有类型,简单,只是不包含AND 语句。我的问题是我不知道是否会设置@serie_type,因此我希望有这样的东西:

/* pseudocode */
??? = AND (IF @serie_type IS NOT NULL S.Type = @serie_type)

这是一个简化版的程序:

CREATE PROCEDURE Report_CompanySerie
    @company    INT,
    @serie_type INT,
    @from       DATE,
    @to         DATE
AS
BEGIN
    SELECT
        *
    FROM Company C
        JOIN Series S ON S.Company_FK = C.Id
    WHERE C.Id = @company 
        AND S.Created >= @from
        AND S.Created <= @to
/* HERE IS MY PROBLEM */        
        AND ???
END
GO

不想复制选择,因为真正的选择比这个大得多。

【问题讨论】:

标签: sql sql-server tsql select notnull


【解决方案1】:

非常简洁的方法是将您的@serie_type 定义为0。看看下面:

CREATE PROCEDURE Report_CompanySerie
    @company    INT,
    @serie_type INT = 0,
    @from       DATE,
    @to         DATE
AS
BEGIN
    SELECT
        *
    FROM Company C
        JOIN Series S ON S.Company_FK = C.Id
    WHERE C.Id = @company 
        AND S.Created >= @from
        AND S.Created <= @to
/* HERE IS MY PROBLEM */        
        AND (@serie_type = 0 OR S.SerieType = @serie_type)
    END
GO

【讨论】:

    【解决方案2】:

    你也可以在where子句中使用case语句

    其中 e.ZoneId = case when @zoneid=0 then e.zoneid else @zoneid end

    【讨论】:

    • 如何在 S.Type = ISNULL(@serie_type,S.Type) 中添加小于条件而不是“=”
    【解决方案3】:

    无需这样做AND (@serie_type IS NULL OR S.Type = @serie_type),因为 SQL Server 有一个内置函数可以为您执行此逻辑。

    试试这个:

       .
       .
       AND  S.Type = isnull( @serie_type, S.Type)
    

    这会返回

    如果@serie_type 为空,则为true;如果@serie_type 不为空,则@serie_type = S.Type 的结果。

    来自MSDN

    IsNull 用指定的替换值替换 NULL。

    ISNULL ( check_expression , replacement_value )
    

    如果check_expression的值不为NULL,则返回该值; 否则,replacement_value 在隐式返回后返回 如果类型不同,则转换为 check_expression 的类型。

    【讨论】:

    • @jeroenh : 看起来你错了,ISNULL ( check_expression , replacement_value ) - “返回与 check_expression 相同的类型。”
    • @jeroenh - 我已经编辑了这个答案。你错了。我多年来一直在 SQL Server 上使用它。
    • 你说得对,今天学到了新东西。真的很抱歉
    • @Preet Sangha:你说“没必要……”是什么意思?这不是 hack,而是 ANSI SQL 构造,不像 ISNULL 是特定于 T-SQL 的。我不明白为什么“不需要做”这句话,你的意思是有副作用还是什么?此外,从我的角度来看,OR 的条件比ISNULL 干净得多
    • 嗨,我只是说 SQL 服务器内置了一个较短的结构。最终归结为选择,我更喜欢更少的代码。如果 ANSI 合规性是一项要求,那么我的陈述当然是错误的,但我不记得那是一个问题要求。
    【解决方案4】:

    常见的做法是:

    WHERE 
    C.Id = @company          
    AND S.Created >= @from         
    AND S.Created <= @to 
    AND  (@serie_type IS NULL OR S.Type = @serie_type)
    

    【讨论】:

    • 这是一个完美的答案,作为双方的检查。
    猜你喜欢
    • 1970-01-01
    • 2021-11-11
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 2012-03-02
    相关资源
    最近更新 更多