2013-10-04 3 views
3

Если параметр не передан хранимой процедуре, он должен вернуть весь результат.динамический sql в хранимой процедуре не удалось получить требуемый результат

Если я прохожу какой-то один параметр, то значение должно отображаться в соответствии с параметром

alter proc SearchEmployee --'','','','' 
    @Name varchar(50)=null, 
    @Age int=null, 
    @Gender varchar(50)=null, 
    @Email varchar(50)=null 
as 
begin 

    declare @sql varchar(max), @sqlwhere varchar(max) 
    set @sqlwhere = ''; 

    set @sql = 'select * from employee' 

    if ((@Name is not null) and @Name <> '') 
    begin 
     set @sqlwhere=' Name='+ @Name 
    end 
    else if ((@Age is not null) and @Age <> '') 
    begin 
     set @sqlwhere='and Age='+ cast(@Age as varchar(50)) 
    end 
    else if ((@Email is not null) and @Email <> '') 
    begin 
     set @sqlwhere=' and email='+ @Email 
    end 
    else if ((@Gender is not null) and @Gender <> '') 
    begin 
     set @sqlwhere=' and Gender='+ @Gender 
    end 

    if (@sqlwhere <> '') 
    begin 
     set @sql = @sql + ' where ' + @sqlwhere; 
    end 
    else 
    begin 
     set @sql = @sql; 
    end 

    print @sql 
    exec (@sql) 
end 

employee стол

Name Age Gender email 
anurag 24 Male [email protected] 
abhi 22 Male [email protected] 
ruchi 23 Female [email protected] 
siba 24 Male [email protected] 
mukua 24 Male [email protected] 
prachi 24 Female [email protected] 
preeti 24 Female [email protected] 

Исполнительной

SearchEmployee '','','','' 

дает мне все результаты.

Но выполнение ниже дает ошибку

SearchEmployee 'anurag','','',''` 

select * from employee where Name=anurag 

Ошибка:

Msg 207, Level 16, State 1, Line 1
Invalid column name 'anurag'.

Пожалуйста, помогите мне изменить запрос. И где я делаю неправильно?

+1

Это 'select * from employee, где Name = anurag' пытается найти строки, где столбец' Name' соответствует значению столбца anurag', но есть ** нет ** колонка 'anurag'! Вы должны поместить свои строковые значения в одинарные кавычки! ** - 'select * от сотрудника, где Name = 'anurag'' –

ответ

2

Вы забыли о оберточной значения VARCHAR/NVARCHAR одинарные кавычки.
Также, если вы не укажете @Name, ваш динамический запрос будет иметь, например, where and Age = ... часть, т. Е. Будет иметь нежелательный and перед первым условием фильтра.
Более того, в вашей реализации может быть только одно условие фильтра (ноль или одно) из-за if else if цепи. Но, похоже, вы хотите использовать все параметры передачи (то есть не нуль).

Кстати, нет необходимости использовать динамический запрос. Например, вы можете использовать этот запрос:

select 
    * 
from employee 
where 
    Name = isnull(@Name, Name) 
    and Age = isnull(@Age, Age) 
    and email = isnull(@Email, email) 
    and Gender = isnull(@Gender, Gender) 

или

select 
    * 
from employee 
where 
    (@Name is null or Name = @Name) 
    and (@Age is null or Age = @Age) 
    and (@Email is null or email = @Email) 
    and (@Gender is null or Gender = @Gender) 

UPD. Ответьте на вопрос в комментариях. Да, это может быть сделано. И снова ISNULL (или сливаются) функция:

-- remove set @sqlwhere = '' in top of the query so @sqlwhere 
-- will be null - it's usefull. 
-- also change if (@sqlwhere <> '') to if (@sqlwhere is not null) 

set @sqlwhere = isnull(@sqlwhere + ' and ', '') 
       + ' Age = ''' + cast(@Age as varchar(50)) + ''' '; 

-- as you see, I also added single quotes wrapping for @Age value 

isnull имеет простую логику - если первый параметр is not null затем возвращали еще вернется второй параметр. Также есть правило в sql, если значение null появляется в арифметической операции или в конкатенации строк (наш случай), тогда весь результат будет null. Так что если @sqlwhere is null, то @sqlwhere + ' and ' также будет null.Это означает, что нет никаких условий в @sqlwhere, тогда нет необходимости в слове and.
Надеюсь, что это ясно :)

+0

Превосходное объяснение .. Я попробовал оба. И оба работают нормально. – anurag

+0

Но как вы сказали: «Также, если вы не укажете @Name, ваш динамический запрос будет иметь, например, где и Age = ... part, то есть будет иметь нежелательные и перед первым условием фильтрации». , так можно ли это обрабатывать в динамическом запросе? Есть ли способ сделать то же самое в динамическом запросе? – anurag

+0

@anurag посмотреть на часть обновления в ответ – pkuderov

1

Лучший способ отлаживать этот тип динамического SQL - просто удалить exec (@sql) и просто распечатать SQL-заявление. Затем вы можете использовать этот оператор для работы с запросом до его правого положения, а затем внести корректировки в код на основе сделанных вами изменений.

В этом случае вы обнаружите, что вам не хватает апострофов вокруг параметра. Попробуйте что-то вроде этого:

set @sqlwhere=' Name='+ '''' + @Name + '''' 

ли, что для любого параметра, который проходит в тексте

+0

Yaa его работа. Но у меня есть один вопрос. Почему требуется 4 цитаты. Я немного смущен здесь. Пожалуйста, объясните мне .. это будет полезно для меня ... – anurag

+0

Это похоже на '' '' + @Name + '' ''. Первая цитата - начало первой строки. Затем следующие два кавычки - одинарная кавычка. Затем закройте строку. Таким образом, это делает «». Затем + @ Name +. Затем начинается вторая строка. Затем следующие две цитаты делают одну цитату. Тогда последняя цитата - это конец второй строки. Правильно ли я понимаю? – anurag

+0

В принципе, чтобы «показать» в динамическом sql, вы должны показать его как «». Причина этого в том, что сингл «никогда не появится, потому что он относится к началу и концу строки. Используя 4 .. первые 2 говорят, что его строка и средняя 2 отменяют друг друга и становятся единственными ». Я знаю, что это смущает. Я всегда просто изучал это как использовать 4 апострофа для 1. – logixologist

Смежные вопросы