如果存储过程中的参数值为空,如何忽略该参数

2024-01-04

我有一个存储过程,我必须在其中连接 10 个表并使用WHERE根据存储过程中传递的参数过滤记录的条件。例如:

create procedure proc1
    @var1 varchar(100) = null,
    @var2 varchar(100) = null,
    @var3 varchar(100) = null,
    @var4 varchar(100) = null,
    ........   
    @var10 varchar(100) = null
as
begin
    insert into #a
    select * from
    (
        select * from 
            tab1 as a
            inner join tab2 as b on a.rollnumber = b.rollnumber
            inner join tab3 as c on c.city = b.city
            ........
            inner join tab10 as j on J.id = i.id
        where 
            a.id = isnull(@var1,a.id) and 
            b.id = isnull(@var2,b.id) and 
            c.id = isnull(@var3,c.id) and 
            ...........
            J.id = isnull(@var10,j.id)
    ) as abc

    if (select count(*) from #a) < 10 
    begin
        select * from #a
    end
    else 
    begin
        print 'Cannot display the records as count is more than 10'
    end
end

上面的存储过程工作正常,但是速度很慢,因为有 10 个条件WHERE条款。我想要的是如果某些参数未提供给存储过程则跳过条件。例如,如果仅向存储过程传递 3 个参数,则WHERE子句应该跳过其余的参数WHERE条款。这将使该过程更加高效。因此,如果@var1没有通过,所有的值a.id应该被退回。


有一篇很好的文章T-SQL 中的动态搜索条件 http://www.sommarskog.se/dyn-search-2008.html作者:厄兰·索马斯科格。他解释了几种可以使用的方法,并比较了按照 @lad2025 建议构建动态 SQL 和使用OPTION(RECOMPILE).

我个人使用OPTION(RECOMPILE) https://msdn.microsoft.com/en-us/library/ms181714.aspx在这些查询中。您使用 SQL Server 2008,因此此选项是一个不错的选择。如果您确实采用动态 SQL 路线,请务必阅读他的另一篇文章动态 SQL 的诅咒和祝福 http://www.sommarskog.se/dynamic_sql.html.

所以,你的程序变成这样:

create procedure proc1
    @var1 varchar(100) = null,
    @var2 varchar(100) = null,
    @var3 varchar(100) = null,
    @var4 varchar(100) = null,
    ........   
    @var10 varchar(100) = null
as
begin
    insert into #a
    select * from
    (
        select * 
        from
            tab1 as a
            inner join tab2 as b on a.rollnumber = b.rollnumber
            inner join tab3 as c on c.city = b.city
            ........
            inner join tab10 as j on J.id = i.id
        where 
            (a.id = @var1 OR @var1 IS NULL)
            and (b.id = @var2 OR @var2 IS NULL)
            and (c.id = @var3 OR @var3 IS NULL)
            ...........
            and (J.id = @var10 OR @var10 IS NULL)
    ) as abc
    OPTION(RECOMPILE);

    if (select count(*) from #a) < 10 
    begin
        select * from #a
    end
    else 
    begin
        print 'Cannot display the records as count is more than 10'
    end
end

顺便说一句,目前尚不清楚您想通过检查来实现什么目的count(),但也许你需要的只是简单TOP(10)最多返回 10 个第一行。请务必添加ORDER BY条款如果你确实使用TOP一致地返回结果。如果您不知道,您可以使用过程的另一个参数来指示要返回的最大行数并在TOP(@ParamMaxRowCount)。有时返回结果集有时只打印一条消息的存储过程并不常见。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如果存储过程中的参数值为空,如何忽略该参数 的相关文章

随机推荐