参数化WHERE子句?

时间:2010-06-10 13:28:17

标签: sql sql-server-2008 stored-procedures parameters

我需要为SQL Server 2008编写一个存储过程来执行大型select查询,我需要它通过过程参数指定过滤类型来过滤结果。我找到了一些像这样的解决方案:

create table Foo(
   id bigint, code char, name nvarchar(max))
go

insert into Foo values
 (1,'a','aaa'),
 (2,'b','bbb'),
 (3,'c','ccc')
go

create procedure Bar
       @FilterType  nvarchar(max),
       @FilterValue nvarchar(max) as
begin
    select * from Foo as f
    where case @FilterType
          when 'by_id'   then f.id
          when 'by_code' then f.code
          when 'by_name' then f.name end
          = 
          case @FilterType
          when 'by_id'   then cast(@FilterValue as bigint)
          when 'by_code' then cast(@FilterValue as char)
          when 'by_name' then @FilterValue end
end
go

exec Bar 'by_id', '1';
exec Bar 'by_code', 'b';
exec Bar 'by_name', 'ccc';

我发现这种方法不起作用。可以将所有列转换为nvarchar(max)并将它们作为字符串进行比较,但我认为这会导致性能下降。

是否可以在不使用where之类的结构的情况下参数化存储过程中的EXEC sp_executesql子句?

4 个答案:

答案 0 :(得分:2)

试试这个

create procedure Bar 
       @FilterType  nvarchar(max), 
       @FilterValue nvarchar(max) as 
begin 
    select * from Foo as f 
    where 
        (@FilterType ='by_id'   and f.id =cast(@FilterValue as bigint) )
        OR
        (@FilterType ='by_code'   and f.code =cast(@FilterValue as char) 
        OR
        (@FilterType ='by_name'   and f.name =@FilterValue

end 
go 

答案 1 :(得分:2)

对于大型过滤器要求,这可能会变得有点长,但我认为它可能更高效/更容易阅读/维护:

create procedure Bar
       @Id int,
       @Code nvarchar,
       @name nvarchar
begin
    select * from Foo as f
    where (@id = -1 or f.ID = @id)
    and (@Code = '' or f.Code = @Code)
    and (@Name = '' or f.Name = @Name)
end
go

exec Bar 1, '', ''
exec Bar -1, 'code', ''
exec Bar -1, '', 'name'

这也允许您同时过滤多个项目。

答案 2 :(得分:0)

declare @field varchar(20)

declare @value varchar(100)

set @field = 'customerid'
set @value = 'ALFKI'

set @field = 'Country'
set @value = 'Germany'

set @field = 'ContactTitle'
set @value = 'Owner'

select * from customers
where (customerid = (case when @field = 'customerid' then  @value else customerid end)
and ContactTitle = (case when @field = 'ContactTitle' then  @value else ContactTitle end)
and country = (case when @field = 'Country' then  @value else country end))

示例适用于Northwind数据库 希望这会有所帮助。

编辑:评论以上@field@value的3个值中的任意2个。

答案 3 :(得分:0)

如果您没有很多过滤条件,可以考虑创建委托函数并将请求分派给相应的函数。如,

create procedure Bar
       @FilterType  nvarchar(max),
       @FilterValue nvarchar(max) as
begin
    case @FilterType
          when 'by_id'   then FilterById(@FilterValue)
          when 'by_code' then FilterByCode(@FilterValue)
          when 'by_name' then FilterByName(@FilterValue)
          end
end
go