2010-04-02 23 views
7

मैं चाहता हूं कि मैं अपने क्लॉज के लिए एसक्यूएल सर्वर 2005 (जो मुझे पता नहीं है) में निम्न की तरह कुछ कर सकता है। कभी-कभी @teamID (एक संग्रहीत प्रक्रिया में पारित) एक मौजूदा टीमआईडी का मूल्य होगा, अन्यथा यह हमेशा शून्य होगा और मैं टीम तालिका से सभी पंक्तियां चाहता हूं।एसक्यूएल में सशर्त ऑपरेटर जहां क्लॉज

मैंने केस का उपयोग करके शोध किया और ऑपरेटर को पूरे वक्तव्य के पहले या बाद में आने की आवश्यकता है जो मुझे @teamid के मूल्य के आधार पर एक अलग ऑपरेटर रखने से रोकती है। मेरे चयन कथन को डुप्लिकेट करने के अलावा कोई सुझाव।

declare @teamid int 
    set @teamid = 0 

    Select Team.teamID From Team 
     case @teamid 
     when 0 then 
      WHERE Team.teamID > 0 
     else 
      WHERE Team.teamID = @teamid 
     end 

उत्तर

18

आप क्या कर सकते हैं कि एक मामले के बिना:

SELECT Team.teamID 
FROM Team 
WHERE (@teamid = 0 AND Team.teamID > 0) 
     OR (@teamid <> 0 AND Team.teamID = @teamid) 
2

के बारे में क्या:

Select Team.teamID From Team Where (@teamid=0 and team.teamID>0) or (@teamid<>0 and [email protected]) 
5

गतिशील एसक्यूएल का उपयोग कर के बिना, सबसे शक्तिशाली विकल्प है:

IF @teamid = 0 
    BEGIN 

    SELECT t.teamid 
     FROM TEAM t 
    WHERE t.teamid > 0 

    END 
ELSE 
    BEGIN 

    SELECT t.teamid 
     FROM TEAM t 
    WHERE t.teamid = @teamid 

    END 

डायनामिक एसक्यूएल का उपयोग करना:

DECLARE @SQL NVARCHAR(4000) 
    SET @SQL = 'SELECT t.teamid 
       FROM TEAM t 
       WHERE 1 = 1 ' 

    SET @SQL = @SQL + CASE @teamid 
         WHEN 0 THEN ' AND t.teamid > 0 ' 
         ELSE ' AND t.teamid = @teamid ' 
        END 

BEGIN 

    EXEC sp_EXECUTESQL @SQL N'@teamid INT', @teamid 

END 

सावधान रहें कि sp_EXECUTESQL प्रश्न योजना को कैश करता है, जबकि EXEC नहीं होगा। इस पढ़ें: http://www.sommarskog.se/dynamic_sql.html

+1

नहीं सोचेंगे कि गतिशील एसक्यूएल या दो आईएफ ब्लॉक की अतिरिक्त जटिलता इसके लायक है, जब तक कि आप चीन के नेशनल स्पोर्ट एसोसिएशन ऑफ चाइना डेटाबेस से पूछताछ न करें ;-) – Andomar

+0

लेकिन जटिलता और रखरखाव लागत हानि के प्रदर्शन का प्रदर्शन लाभ है ? – tpdi

+0

सभी तीन विकल्पों में उनके पेशेवर और विपक्ष हैं - एंडोमर के सुझाव में एक ब्रैकेट याद करते हैं, और चीजें इरादे के अनुसार काम नहीं करेंगे। –

0

आप सभी रिकॉर्ड के रूप में अशक्त का इलाज कर सकता है:

WHERE Team.teamID = ISNULL(@teamid, Team.teamID) 
2

Andomar के जवाब से भी सरल, और कहा कि आईडी संभालने कभी नहीं 0 है (सबसे ऑटो वेतन वृद्धि आईडी के लिए के रूप में) है

SELECT Team.teamID 
FROM Team 
WHERE @teamid = 0 or Team.teamID = @teamid; 

यह अनुमान हमेशा सत्य होता है जब @teamid शून्य होता है, और अन्यथा केवल तभी सत्य होता है जब यह किसी विशेष पंक्ति की टीम से मेल खाता है Id।

नोट हालांकि: यह Sybase 11 या ऊपर पर बहुत कुशलता से काम करता है; यह एमएस एसक्यूएल सर्वर 2003 पर काफी अक्षमता से काम किया; मुझे नहीं पता कि यह एमएस एसक्यूएल सर्वर के वर्तमान संस्करण पर कैसे काम करता है।

इसके अलावा, आप मामले का उपयोग कर सकते हैं; आपको सिर्फ इस मामले में कहां रखना है, इस मामले में जहां खंड नहीं है। तो आपकी मूल क्वेरी होगा:

Select Team.teamID 
From Team 
where 
    case when @teamid = 0 then 0 else Team.teamID end = @teamId; 

ध्यान दें कि यह कम कुशल होने की संभावना है, हालांकि, के रूप में यह प्रति पंक्ति का मूल्यांकन किया और किया जाना चाहिए होगा एक पूर्ण तालिका स्कैन में भी संभावना परिणाम।

@teamid शून्य नहीं होने पर इंडेक्स का उपयोग करने के लिए ऊपर दिए गए फॉर्म को स्मार्ट क्वेरी ऑप्टिमाइज़र (आपका माइलेज आपके आरडीबीएमएस पर निर्भर करता है) द्वारा फिर से लिखा जा सकता है।

+0

+1 आपका पहला जवाब कमाल है। यहां तक ​​कि सरल भी हो सकता है '@teamid (0, TeamID) '! – Andomar

+0

धन्यवाद! लेकिन एक सूची का उपयोग शायद अनुकूलन में नहीं होगा। – tpdi

+0

एक सूची में सिर्फ वाक्य रचनात्मक चीनी है। मुझे लगता है कि ऑप्टिमाइज़र इसे देखने से पहले 'इन (बी, सी)' को 'ए = बी या ए = सी' तक बढ़ाया गया है – Andomar

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