3

如果没有参数传递给存储过程,它应该返回所有结果。

如果我传递任何一个参数,则值应根据参数显示

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    anu@gmail.com
abhi    22  Male    abhi@gmail.com
ruchi   23  Female  ruchi@gmail.com
siba    24  Male    siba@gmail.com
mukua   24  Male    mukua@gmail.com
prachi  24  Female  prachi@gmail.com
preeti  24  Female  preeti@gmail.com

执行

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

给我所有的结果。

但是执行以下会出错

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

select * from employee where  Name=anurag

错误:

消息 207,级别 16,状态 1,第 1 行
无效的列名称“anurag”。

请帮我修改查询。我在哪里做错了?

4

2 回答 2

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)

升级版。在评论中回答问题。是的,这是可以做到的。再次通过 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文字。
希望很清楚:)

于 2013-10-04T18:20:44.440 回答
1

调试这种类型的动态 SQL 的最佳方法是简单地删除exec (@sql)并打印 SQL 语句。然后,您可以使用该语句处理查询直到其正确,然后根据您所做的更改在代码中进行调整。

在这种情况下,您会发现参数周围缺少撇号。尝试这样的事情:

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

对传入文本的任何参数执行此操作

于 2013-10-04T18:03:35.027 回答