2014-09-16 6 views
5

में खंड जहां मैं एक प्रश्न के लिए खंड कहां लिख रहा हूं, जिस पर मैं काम कर रहा हूं। मैं क्रिस्टल रिपोर्ट में कोड आयात कर रहा हूं और मैं मूल रूप से यह कहने की कोशिश कर रहा हूं कि परिवर्तनीय 'प्रकार' इस दिनांक सीमा के लिए 'निर्माण' पर सेट है, जहां किसी अन्य दिनांक सीमा के लिए खंड कहां चलाया जाता है। यह मुझे एक त्रुटि दे रहा है। मैं यह पहचानने के लिए प्रतीत नहीं कर सकता कि मेरे वाक्यविन्यास में क्या गलत है। किसी की मदद करें?सीएसईई कथन जहां tsql क्वेरी

DECLARE @Date1 DATETIME 
DECLARE @Date2 DATETIME 
DECLARE @type VARCHAR(20) 
SET @Date1 = '2010-1-1' 
SET @Date2 = '2010-2-1' 
SET @type = '{?DateType}' 

select * 
from filled 
WHERE 
    (CASE WHEN @type = 'create' THEN 
    filled.CREATEDON >= @Date1 
    AND filled.CREATEDON < DATEADD(d, +1, @Date2) 
    WHEN @type <> 'create' THEN 
    filled.datefilled >= @Date1 
    AND filled.datefilled < DATEADD(d, +1, @Date2) 
    END) 
+0

आपको क्या त्रुटि मिल रही है? और आपके पास '@ type = 'create'' के लिए 2 चेक क्यों हैं? – Andrew

+0

लेकिन फिर क्रिस्टल रिपोर्ट के खिलाफ क्यों चिह्नित किया जाता है जब यह सभी SQL – aMazing

+0

है क्योंकि मैं क्रिस्टल में क्वेरी आयात कर रहा हूं। – Barzul

उत्तर

12

आप एक case बयान

WHERE ((@type = 'create' and filled.CREATEDON >= @Date1 AND filled.CREATEDON < DATEADD(d, +1, @Date2)) or 
     (@type <> 'create' and filled.datefilled >= @Date1 AND filled.datefilled < DATEADD(d, +1, @Date2)) 
    ) 

इस गैर sensical तर्क आप case बयान में राशि छोड़ देता है की जरूरत नहीं है। दोनों स्थितियों में @type के लिए समान मूल्य है। मुझे लगता है कि एक टाइपो है।

+0

हां वास्तव में यह एक टाइपो था <>। धन्यवाद। – Barzul

7

में एक मामला अभिव्यक्ति का उपयोग करते हुए जहां खंड संभव है, लेकिन आम तौर पर यह बचा जा सकता है, और AND/OR का उपयोग कर फिर से लिखा एक, आपके मामले में यह होगा:

WHERE( @Type = 'create' 
    AND filled.CREATEDON >= @Date1 
    AND filled.CREATEDON < DATEADD(d, +1, @Date2) 
    ) 
OR ( @Type != 'create' 
    AND filled.datefilled >= @Date1 
    AND filled.datefilled < DATEADD(d, +1, @Date2) 
    ) 

हालांकि प्रश्नों इस तरह आम तौर पर करने से इनकी उत्पादन योजना है। आप IF/ELSE तर्क यदि संभव हो उपयोग करना चाहिए:

IF @Type = 'create' 
BEGIN 
    SELECT * 
    FROM Filled 
    WHERE Filled.CreatedOn >= @Date1 
    AND  Filled.CreatedOn < DATEADD(DAY, 1, @Date2) 
END 
ELSE 
BEGIN 
    SELECT * 
    FROM Filled 
    WHERE Filled.DateFilled >= @Date1 
    AND  Filled.DateFilled < DATEADD(DAY, 1, @Date2) 
END 

इस का कारण यह @type का मूल्य संकलन समय पर इसलिए नहीं जाना जाता है, इसलिए अनुकूलक चाहे वह DateFilled या CreatedOn पर खोज करने के लिए की आवश्यकता होगी पता नहीं है, है किसी भी कॉलम पर एक इंडेक्स का उपयोग करने की योजना नहीं बना सकता (यदि कोई मौजूद है), तो इंडेक्स उपलब्ध होने पर ध्यान दिए बिना टेबल स्कैन करेगा। जबकि यदि आप IF/ELSE के साथ तर्क को अलग करते हैं तो इससे कोई फर्क नहीं पड़ता कि @type का मूल्य क्या है, IF की प्रत्येक शाखा के लिए एक योजना बनाई गई है, और प्रत्येक शाखा में ऑप्टिमाइज़र जानता है कि कौन सा कॉलम खोजा जाएगा, और इसका उपयोग करने की योजना बना सकते हैं उचित सूचकांक

तुम भी UNION ALL उपयोग कर सकते हैं:

SELECT * 
FROM Filled 
WHERE Filled.CreatedOn >= @Date1 
AND  Filled.CreatedOn < DATEADD(DAY, 1, @Date2) 
AND  @Type = 'create' 
UNION ALL 
SELECT * 
FROM Filled 
WHERE Filled.DateFilled >= @Date1 
AND  Filled.DateFilled < DATEADD(DAY, 1, @Date2) 
AND  @Type <> 'create'; 

फिर, अगर अनुक्रमित DateFilled या CreatedOn पर मौजूद इस एक योजना OR का उपयोग करने से उन्हें का उपयोग करता है निर्माण करने के लिए और अधिक होने की संभावना है।

संबंधित मुद्दे