2010-06-10 18 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) पर डालना संभव है और उन्हें तारों के रूप में तुलना करें, लेकिन मुझे लगता है कि यह प्रदर्शन में गिरावट का कारण बन जाएगा।

क्या जैसी संरचनाओं का उपयोग किये बिना संग्रहीत प्रक्रिया में where खंड को पैरामीट्रिज़ करना संभव है?

+0

क्या आपने LINQ से SQL की कोशिश की है? –

उत्तर

2

यह हो सकता है थोड़ा और अधिक लंबे समय तक बड़े फिल्टर आवश्यकताओं के लिए चढ़ा हुआ है, लेकिन मुझे लगता है कि यह शायद अधिक performant/पढ़ने में आसान/बनाए रखने:

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.Name = @ नाम। (यह नल के साथ काम करेगा, जब तक कि आप कॉलम की खोज नहीं कर रहे थे जो कि शून्य पर सेट किए गए थे।) –

+0

@ फिलिप केली - आप जो फ़िल्टर करना चाहते हैं उस पर निर्भर करता है - यदि आप वापस लौटना चाहते हैं तो आप किसी भी फ़ील्ड पर मेल खाते हैं, तो वह काम करेगा। – 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 सर्वर सभी 'और' शाखाओं को निष्पादित करने का प्रयास करता है और दाईं ओर डेटा को कनवर्ट करने में विफल रहता है ... – ControlFlow

+0

क्या आप वाकई हैं? या भाग इसका ख्याल रखेगा – 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)) 

उदाहरण करेंनॉर्थविंडडेटाबेस के लिए अनुकूलित है की कोशिश करो।
उम्मीद है कि यह मदद करता है।

संपादित करें: उपरोक्त के लिए @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 
संबंधित मुद्दे