2017-06-02 3 views
2

aspxページのテキストボックス入力テキストに基づいてデータベースを検索するストアドプロシージャを作成しています。パラメータがnullまたは空のときにwhere句をスキップまたは無視する方法

このストアドプロシージャは正常に機能しますが、問題があります。

時には@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 

ありがとうございました。

+0

[ISNULLチェッカー]を見てみてください(https://stackoverflow.com/questions/4224991/sql-server-checking-an-input-param-if-not-null-and-using-それはどこに) – OnDoubt

答えて

1

非常に一般的な構造がある:あなたの文の最後に(再コンパイル)ヒントは、それらの値で変数を置き換える「の後に」最適化計画をチェックするために、SQL Serverを語っていると

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

。そうすることで、パラメータがnullのときに条件を完全に無視し、通常は最適な実行になります(非常に複雑な文でのみ、SQLエンジンがより良い実行計画を見つけるためにはさらに多くのことを行う必要があります)。

with(再コンパイル)節を使用すると、実行するたびに(新しいものを再利用するのではなく)新しいプランをチェックすることに注意することも重要です。したがって、文が2番目に数回実行される場合は、パラメータ化された動的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を指定された置換値に置き換えることができます。この場合

@DeptNameが、その後DT.DisplayNameの値に置き換えるnullの場合。同じことが@DutyNameに適用されます。

論理関数IIFは空の値をチェックするために使用されますが、これはSQL2012のバージョンを開始します。それ以外の場合はSQL2008以降のバージョンの場合はCASE expressionです。

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 
関連する問題