2017-06-02 207 views
2

我正在编写一个关于基于aspx页面文本框输入文本搜索数据库的存储过程。如何在参数为空或空时忽略或忽略where子句

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

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

所以我想跳过或忽略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 

谢谢。

+0

请采取[ISNULL检查]一看(https://stackoverflow.com/questions/4224991/sql-server-checking-an-input-param-if-not-null-and-using-它功能于其中) – OnDoubt

回答

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) 

使用(重新编译)在你的发言结束提示告诉SQL Server将其值替换变量“后”检查优化方案。这样做可以在参数为空时完全忽略条件,通常会导致最佳执行(只有在非常复杂的语句中,为了帮助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) 
0

添加一个额外的@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 
0

你可以试试这个。

使用ISNULL可以用指定的替换值替换NULL。

在这种情况下,IF @deptname为空,然后用DT.DisplayName的值替换它。同样适用于@职务名称

逻辑作用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