2012-06-19 45 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 

它的复杂,但是只有这种方式能够

相关问题