2010-06-10 3 views
5

select 쿼리를 수행하기 위해 SQL Server 2008 저장 프로 시저를 작성해야하며 프로 시저의 매개 변수를 통해 필터링 유형을 지정하여 결과를 필터링해야합니다. 다음과 같은 몇 가지 해결책을 찾았습니다.WHERE 절을 매개 변수로 지정 하시겠습니까?

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)으로 전송하고 문자열로 비교할 수는 있지만 성능이 저하 될 것으로 생각됩니다.

EXEC sp_executesql과 같은 구문을 사용하지 않고 저장 프로 시저에서 where 절을 매개 변수화 할 수 있습니까?

+0

LinQ to SQL을 사용해 보셨나요? –

답변

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' 

을 동시에.

+0

알아서, 그래서처럼 또는 조항의 첫 번째 부분을 삭제합니다 ... f.ID = @id 또는 F를. 코드 = @ 코드 또는 f. 이름 = @ 이름. (null로 설정된 열을 검색하지 않는 한이 값은 null과 함께 작동합니다.) –

+0

@Philip Kelley - 필터에서 수행 할 항목에 따라 다름 - 전달 된 필드 중 어디에 일치하는지 반환하려는 경우, 그때는 효과가있었습니다. – Paddy

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 [email protected] 

end 
go 
+0

감사합니다,하지만 작동하지 않습니다 ... SQL Server는 모든'and' 분기를 실행하려고 시도하고 오른쪽에있는 데이터를 변환하지 못합니다 ... – ControlFlow

+0

정말입니까? 수술실 부분은 당신이 ORS와 외부 "와"의를 대체 할 수있는 생각이 – Madhivanan

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 주석.

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 
관련 문제