如果没有参数传递给存储过程,它应该返回所有结果。
如果我传递任何一个参数,那么值应按参数
显示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
错误:
Msg 207,Level 16,State 1,Line 1
列名称'anurag'无效。
请帮我修改查询。我在哪里做错了?
答案 0 :(得分: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(或coalesce)函数:
-- 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
字就没有必要了
希望很清楚:)
答案 1 :(得分:1)
调试此类动态SQL的最佳方法是简单地删除exec (@sql)
并只打印SQL语句。然后,您可以使用该语句处理查询,直到其右侧,然后根据您所做的更改在代码中进行调整。
在这种情况下,您会发现参数周围缺少撇号。尝试这样的事情:
set @sqlwhere=' Name='+ '''' + @Name + ''''
对于传入文本的任何参数
执行此操作