我使用LIKE存储过程(SP)。让我们简化为:SELECT * FROM customers WHERE name LIKE'%'+ @query +'%'。
我想用它来进行(可选的)完全匹配搜索而不改变存储过程,但是有一个棘手的参数;)
有没有办法用聪明的@query“取消”2'%'?
当然,使用变量来保存两个%符号,并在需要精确匹配时将其设置为空字符串。
使用Vinko的基本答案,你可以拥有
create procedure match @needle varchar(max), @mode int as begin declare @like char(1); set @like = case when @like = 1 then '%' else '' end SELECT * FROM customers WHERE name LIKE (@like + @needle + @like) end
为什么必须这样?这样的事情更有意义(未经测试,可能有一些错误/错别字)
create procedure match
@needle varchar(max), @mode int
as
begin
declare @query varchar(max)
if @mode = 1 begin
set @query = 'SELECT * FROM customers WHERE name LIKE ''%' + @needle + '%'''
end
else begin
set @query = 'SELECT * FROM customers WHERE name = ''' + @needle + '''
end
exec @query
end
编辑:由于您希望避免更改原型,您可以模拟mode参数,或者只是使用%s发送字符串
create procedure match
@modeneedle varchar(max)
as
begin
declare @mode varchar(1)
declare @needle varchar(max)
set @mode=substring(@modeneedle,1,1)
set @needle=substring(@modeneedle,2,len(@modeneedle))
declare @query varchar(max)
if @mode = '1' begin
set @query = 'SELECT * FROM customers WHERE name LIKE ''%' + @needle + '%'''
end
else begin
set @query = 'SELECT * FROM customers WHERE name = ''' + @needle + '''
end
exec @query
end
注意:我永远不会推荐这样做。这表明你真的做错了。话虽如此,如果你真的想做自己的SQL注入,你的存储过程是这样的:
set @query = 'SELECT * FROM tmpCustomer WHERE name LIKE ''%' + @needle + '%'''
exec (@query)
然后像这样运行存储过程:
exec match '~~~~THIS WILL NEVER BE IN THE DATABASE~~~~'' OR name = ''testing'' OR ''notapercentagesign'' = '''
...应该对“测试”进行完全匹配搜索。
但坦率地说,如果你需要使用自己的计算机系统做这样的事情,那么你就输了,这里有一些证据:像这样运行你的存储过程:
exec match '''; DELETE FROM Customer; SELECT * FROM Customer WHERE name LIKE '' '
...将删除所有客户记录:)
尝试:
select *
from customers
where case @exact then name = @query else name like '%' + @query + '%' end;