2012-06-19 69 views
3

我正在編寫一個帶有3個參數的存儲過程,而且where子句根據其中一個參數進行更改。是否有可能以這種方式編寫SQL查詢 -若要在存儲過程中的where子句中使用

CREATE PROCEDURE [dbo].[VendorVettingModal] @column NVarchar (50), @applicanttype NVarchar (10), @donotuse int AS 

       declare @column NVarchar (50), @applicanttype NVarchar (10), @donotuse int 

    select a.Id, a.Firstname, rs.Status,cs.ClearanceStatus 
    from applicant a 
    left join ReviewStatus rs on a.ReviewStatus = rs.Id 
    left join ClearanceStatus cs on a.ClearanceStatus = cs.Id 
    where 
    if(@column = 'Recruiting') 
    begin 
     a.applicanttype = @applicanttype and a.reviewstatus = 7 and a.donotuse = @donotuse  
    end 
    else if(@column = 'Clearance') 
    begin 
     a.applicanttype = @applicanttype and (a.reviewstatus != 7 or a.reviewstatus is null) and a.donotuse = @donotuse  
    end 

而不是寫這種方式?因爲我有大約20-25列和更多的連接,並且在這裏定義了params。我只是試圖讓它在這裏變得更簡單。

CREATE PROCEDURE [dbo].[VendorVettingModal] @column NVarchar (50), @applicanttype NVarchar (10), @donotuse int AS 

       declare @column NVarchar (50), @applicanttype NVarchar (10), @donotuse int 

    if(@column = 'Recruiting') 
    begin 
     select a.Id, a.Firstname, rs.Status,cs.ClearanceStatus 
     from applicant a 
     left join ReviewStatus rs on a.ReviewStatus = rs.Id 
     left join ClearanceStatus cs on a.ClearanceStatus = cs.Id 
     where 
     a.applicanttype = @applicanttype and a.reviewstatus = 7 and a.donotuse = @donotuse  
    end 
    else if(@column = 'Clearance') 
    begin 
     select a.Id, a.Firstname, rs.Status,cs.ClearanceStatus 
     from applicant a 
     left join ReviewStatus rs on a.ReviewStatus = rs.Id 
     left join ClearanceStatus cs on a.ClearanceStatus = cs.Id 
     where 
     a.applicanttype = @applicanttype and (a.reviewstatus != 7 or a.reviewstatus is null) and a.donotuse = @donotuse  
    end 

回答

5

使用括號:

select a.Id, a.Firstname, rs.Status,cs.ClearanceStatus 
    from applicant a 
    left join ReviewStatus rs on a.ReviewStatus = rs.Id 
    left join ClearanceStatus cs on a.ClearanceStatus = cs.Id 
    where a.applicanttype = @applicanttype 
    and a.donotuse = @donotuse 
    AND ((@column = 'Recruiting' AND (a.reviewstatus = 7)) 
    OR 
    (@column = 'Clearance' AND (a.reviewstatus != 7 or a.reviewstatus is null))) 
+1

你也許可以改善它有點通過分解'a.applicanttype = @ applicanttype'和'a.donotuse = @donotuse' –

+0

@ConradFrix良好的呼叫,更新超過 – msmucker0527

+0

msmucker0527:真棒作品就像我想要的,其實我還有一個,如果在if (@column ='Recruiting') 但我可以使用paranthesis來實現它。 – sarsha

2

你可以這樣做有兩種方式。一種方式使用動態SQL。但是,這不是通用的任何數據庫。另一種方法是構建WHERE子句爲:這對動態SQL

where (case when @column = 'Recruiting' and 
       a.applicanttype = @applicanttype and a.reviewstatus = 7 and a.donotuse = @donotuse 
      then 'True' 
      when @column = 'Clearance' and 
       a.applicanttype = @applicanttype and (a.reviewstatus != 7 or a.reviewstatus is null) and a.donotuse = @donotuse 
      then 'True' 
      . . . 
     end) = 'True' 

兩個優點是,查詢不必進行重新編譯,並在更廣泛範圍的數據庫工程。一個缺點是WHERE子句可能不利用適用的索引。

+0

如果您參數化您的動態sql(並且您始終應該),則第一個優勢不存在,因爲SQL Server *將像靜態SQL一樣緩存查詢計劃。 – DeanOC

-2

Unfortunalety,在Transact-SQL的 「的if-else-if-else語句」 只可以這樣寫:http://msdn.microsoft.com/en-us/library/ms182587.aspx

DECLARE @Number int; 
SET @Number = 50; 
IF @Number > 100 
    PRINT 'The number is large.'; 
ELSE 
    BEGIN 
     IF @Number < 10 
      PRINT 'The number is small.'; 
     ELSE 
      PRINT 'The number is medium.'; 
    END; 
GO 

它的複雜,但是隻有這種方式能夠

相關問題