2017-06-02 99 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