SQL Server中动态查询的存储过程

时间:2012-03-08 16:54:19

标签: sql sql-server

我想创建一个过程,该过程根据参数的输入返回一个表作为字段和运算符...如何使用作为参数字符串传递的运算符选择

ALTER PROCEDURE dbo.sp_getStaffRecord
(
   @deptname varchar(50),
   @dob date,
   @active bit,
   @salary int,
   @firstname varchar(50),
   @lastname varchar(50),
   @OperatorDob varchar(2),
   @OperatorSalary varchar(2)
)
AS
    select 
        st.id, firstname, lastname, deptname, salary, dob,
        (select firstname + ', ' + lastname from StaffTable 
         where firstname = @firstname and lastname = @lastname) as [Reporting To],  
        doj, active 
    from 
        StaffTable st 
    inner join 
        DepartmentTable dt on dt.id = st.dept 
    where 
        dt.deptname = @deptname 
        and 
        (
            if (@OperatorDob = '>=')
               st.dob >= @dob  
            else if (@OperatorDob = '<=') 
               st.dob <= @dob
            else if (@OperatorDob = '=')
               st.dob = @dob
            else if (@OperatorDob = '>')
               st.dob > @dob
            else if (@OperatorDob = '<=')
               st.dob = @dob
         ) 
    and st.active = @active 
    and st.salary >= @salary

    RETURN

3 个答案:

答案 0 :(得分:2)

您无法以您希望的方式使用IF..ELSE。你可以做的是将@OperatorDob的值与它应该执行的逻辑结合起来:

WHERE
   dt.deptname = @deptname 
 AND
(
  (@OperatorDob = '>=' AND st.dob >= @dob)
  OR
  (@OperatorDob = '<=' AND st.dob <= @dob)
  OR
  (@OperatorDob = '=' AND st.dob = @dob)
  OR
  (@OperatorDob = '>' AND st.dob > @dob)
  OR
  (@OperatorDob = '<=' AND st.dob = @dob)
)
 AND st.active = @active 
 AND st.salary >= @salary

如果@OperatorDob值不是上面指定的任何值(例如'!='),那么查询将不会产生任何结果。这可能是一个理想的副作用。

答案 1 :(得分:0)

您可以使用动态SQL执行此操作,但这样做很危险(SQL注入的风险很大)。此外,看起来你可以在一个简单的CASE上拥有这些条件,所以我建议你做这样的事情:

ALTER PROCEDURE dbo.sp_getStaffRecord
        (
            @deptname varchar(50),
            @dob date,
            @active bit,
            @salary int,
            @firstname varchar(50),
            @lastname varchar(50),
            @OperatorDob varchar(2),
            @OperatorSalary varchar(2)
        )
AS
    select  st.id,
            firstname,
            lastname,
            deptname,
            salary,
            dob,
            (select firstname+', '+lastname 
             from StaffTable 
             where firstname = @firstname and lastname = @lastname) 
             as [Reporting To], --Why aren't you just doing @firstname+', '+@lastname 
            doj,
            active 
    from StaffTable st 
    inner join DeapartmentTable dt 
    on dt.id = st.dept 
    where dt.deptname = @deptname and
    case when @OperatorDob = '>=' AND st.dob >= @dob  THEN 1
    when @OperatorDob = '<=' AND st.dob <= @dob THEN 1
    when @OperatorDob = '=' AND st.dob = @dob THEN 1
    when @OperatorDob = '>' AND st.dob > @dob THEN 1
    when @OperatorDob = '<=' AND st.dob = @dob THEN 1 ELSE 0 END = 1
    and st.active = @active 
    and st.salary >= @salary

答案 2 :(得分:0)

试试这个:

where dt.deptname = @deptname  
        and
        (@OperatorDob = '>=' AND st.dob >= @dob) OR
        (@OperatorDob = '=' AND st.dob = @dob) OR
        (@OperatorDob = '>' AND st.dob > @dob) OR 
        (@OperatorDob = '<=' AND st.dob <= @dob) OR
        (@OperatorDob = '<' AND st.dob < @dob) OR 

或者,您可以将整个查询放入CASE .. WHEN块。

相关问题