【问题标题】:How to skip or ignore where clause when parameter is null or empty当参数为空或为空时如何跳过或忽略where子句
【发布时间】:2017-11-03 15:30:09
【问题描述】:

我正在编写一个基于aspx页面文本框输入文本搜索数据库的存储过程。

这个存储过程运行良好,但我有一个问题。

有时@DeptName@DutyName 参数为空或null。

所以当参数值为空时,我想跳过或忽略 where 子句。但我对如何处理这种情况感到困惑。

请给我你的建议。

我的存储过程代码:

DECLARE 
        @CompanyCode    varchar(20)
    ,   @DeptName       nvarchar(20)
    ,   @DutyName       nvarchar(20)


SELECT  
        @CompanyCode    = 'h101'
    ,   @DeptName       = 'IT'
    ,   @DutyName       = 'Manager'


SELECT
        U.ADDisplayName                     AS UserName             
    ,   LOWER(U.UserID)                     AS EmpID
    ,   ISNULL(CPN.CompanyName, '')         AS CompanyCode              
    ,   ISNULL(U.DisplayName_Eng, '')       AS DisplayName_Eng      
    ,   ISNULL(DT.DisplayName, '')          AS DeptName             
    ,   ISNULL(DTY.DutyName, '')            AS DutyName             
    ,   ISNULL(U.CellPhone, '')             AS CellPhone            
    ,   ISNULL(U.ExtensionNumber, '')       AS ExtensionNumber      
    ,   ISNULL(U.FaxNumber, '')             AS FaxNumber            
    ,   ISNULL(U.ChargeJob, '')             AS ChargeJob            
    ,   ISNULL(LOC.LocationName, '')        AS LocationName         
    ,   ISNULL(U.Workplace, '')             AS Workplace            
    ,   ISNULL(U.EMail, '')                 AS EMail                

FROM dbo.tb_User U 
    INNER JOIN dbo.tb_Dept DT
        ON U.MainDeptCode = DT.DeptCode
    INNER JOIN dbo.tb_Company CPN
        ON U.CompanyCode = CPN.CompanyCode
    INNER JOIN dbo.tb_Location LOC
        ON U.LocationCode = LOC.LocationCode
            AND U.CompanyCode = LOC.CompanyCode
            AND U.GroupCode = LOC.GroupCode
            AND U.DetailCode = loc.DetailCode
    INNER JOIN dbo.tb_Duty DTY
        ON U.DutyCode = DTY.DutyCode
            AND U.CompanyCode = DTY.CompanyCode
            AND U.GroupCode = DTY.GroupCode
            AND U.DetailCode = DTY.DetailCode
WHERE   U.CompanyCode   = @companyCode 
    AND DT.DisplayName  like '%' + @DeptName + '%'
    AND DTY.DutyName    like '%' + @DutyName + '%'
Order by DeptName desc

谢谢。

【问题讨论】:

标签: sql-server parameters where-clause


【解决方案1】:

一个很常见的结构是:

WHERE   U.CompanyCode   = @companyCode 
    AND (@DeptName is null or DT.DisplayName like '%' + @DeptName + '%')
    AND (@DutyName is null or DTY.DutyName   like '%' + @DutyName + '%')
    ...
    ...
with (recompile)

语句末尾的 with (recompile) 提示告诉 SQL Server 在用变量值替换变量“之后”检查优化计划。这样做可以在其参数为 null 时完全忽略条件,从而通常导致最佳执行(仅在非常复杂的语句上,您需要做更多的事情以帮助 SQL 引擎找到更好的执行计划)。

还值得注意的是,使用 with (recompile) 子句会强制在每次执行时检查新计划(而不是重用现有计划),因此如果您的句子第二次要执行多次,那么您将更适合使用替代方法,例如参数化动态 SQL。虽然这不是最常见的情况。

PS:如果您的参数也可以是空字符串,则使用 isnull 来检查这两个选项。您仍然需要添加重新编译提示才能以最佳方式执行它。

WHERE   U.CompanyCode   = @companyCode 
    AND (isnull(@DeptName, '') = '' or DT.DisplayName like '%' + @DeptName + '%')
    AND (isnull(@DutyName, '') = '' or DTY.DutyName   like '%' + @DutyName + '%')
    ...
    ...
with (recompile)

【讨论】:

    【解决方案2】:

    在每个子句中添加一个额外的@DeptName is null@DeptName =""

    WHERE   U.CompanyCode   = @companyCode 
        AND ((DT.DisplayName  like '%' + @DeptName + '%') or (@DeptName is null) or (@DeptName =''))
        AND ((DTY.DutyName    like '%' + @DutyName + '%') or (@DeptName is null) or (@DeptName = ''))
    Order by DeptName desc
    

    【讨论】:

      【解决方案3】:

      你可以试试这个。

      使用ISNULL,您可以将NULL 替换为指定的替换值。

      在这种情况下,如果 @DeptName 为空,则将其替换为 DT.DisplayName 的值。这同样适用于 @DutyName

      逻辑函数IIF用于检查空值,但这适用于SQL2012版本,否则CASE expression用于SQL2008或更高版本。

          WHERE   U.CompanyCode   = @companyCode 
                  AND DT.DisplayName  like '%' + ISNULL(IIF(@DeptName = '',NULL,@DeptName),DT.DisplayName) + '%'
                  AND DTY.DutyName    like '%' + ISNULL(IIF(@DutyName = '',NULL,@DutyName),DTY.DutyName) + '%'
          Order by DeptName desc
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-18
        • 2021-01-03
        • 2022-11-28
        • 2020-12-28
        • 1970-01-01
        • 2021-09-30
        • 2022-01-19
        • 1970-01-01
        相关资源
        最近更新 更多