2010-06-10 12 views
5

Ich muss eine gespeicherte Prozedur für SQL Server 2008 für die Durchführung einer großen select Abfrage schreiben und ich brauche es, um Ergebnisse mit Filtertyp über Prozedur Parameter zu filtern. Ich fand einige Lösungen wie folgt:Die WHERE-Klausel parametrisieren?

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'; 

Ich finde, dass dieser Ansatz nicht funktioniert. Es ist möglich, alle Spalten in nvarchar(max) zu konvertieren und sie als Strings zu vergleichen, aber ich denke, dass es zu Leistungseinbußen kommen wird.

Ist es möglich, die where-Klausel in Stored Procedure zu parametrisieren, ohne Konstrukte wie EXEC sp_executesql zu verwenden?

+0

Haben Sie versucht, LinQ zu SQL? –

Antwort

2

Dies kann ein sich wenig langatmig, für große Filteranforderungen, aber ich denke, es ist wahrscheinlich mehr performant/leichter zu lesen/pflegen:

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' 

Dies ermöglicht es Ihnen auch um mehr als ein Einzelteil zu filtern gleichzeitig.

+0

Ich denke, Sie könnten die äußeren "und" s durch ors ersetzen und den ersten Teil der Oder-Klausel löschen, so: ... wobei f.ID = @id oder f. Code = @Code oder f.Name = @Name. (Dies würde mit Nullen funktionieren, außer Sie suchen nach Spalten, die auf null gesetzt wurden.) –

+0

@Philip Kelley - Hängt davon ab, was der Filter tun soll - wenn Sie dorthin zurückkehren möchten, wo Sie auf einem der übergebenen Felder übereinstimmen, dann würde das funktionieren. – Paddy

2

Versuchen Sie, diese

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

danke, aber es funktioniert nicht ... SQL Server versucht, alle 'und' Zweige auszuführen und schlägt fehl, Daten auf der rechten Seite zu konvertieren ... – ControlFlow

+0

Sind Sie sicher? Der OR-Teil wird sich darum kümmern – 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)) 

Beispiel für Northwind-Datenbank angepasst ist.
Hoffe, das hilft.

BEARBEITEN: Kommentieren Sie eine beliebige 2 der 3 Werte für @field und @value für oben.

0

Wenn Sie nicht viele Filterkriterien haben, können Sie Delegatfunktionen erstellen und die Anfrage an die entsprechende senden. ZB

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 
Verwandte Themen