2012-03-08 2 views
1

Я хочу создать процедуру, которая возвращает таблицу на основе ввода пармеров в качестве полей и оператора ... как я могу использовать выбор оператора, который передается как строка параметровСохраненная процедура для динамического запроса в 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 
+1

Как раз так это может быть правильно помечено, с какой версией SQL Server вы работаете? – Yuck

ответ

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 происходит не быть какой-либо из указанных выше (например '!='), то запрос не будет производить любые Результаты. Это может быть желательным побочным эффектом.

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+', '[email protected] 
      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 
+0

thanx sir .... его действительно полезно ... :) –

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 блок.