CASE
एक अभिव्यक्ति है जो एक मान लौटाती है। यह नियंत्रण-प्रवाह के लिए नहीं है, जैसे IF
. और आप IF
. का उपयोग नहीं कर सकते एक प्रश्न के भीतर।
दुर्भाग्य से, CASE
. की कुछ सीमाएँ हैं अभिव्यक्तियाँ जो आपको वह करने के लिए बोझिल बनाती हैं जो आप चाहते हैं। उदाहरण के लिए, CASE
. की सभी शाखाएं अभिव्यक्ति को एक ही प्रकार वापस करना चाहिए, या एक ही प्रकार के लिए स्पष्ट रूप से परिवर्तनीय होना चाहिए। मैं तार और तिथियों के साथ कोशिश नहीं करता। आप CASE
का भी उपयोग नहीं कर सकते क्रमबद्ध दिशा निर्दिष्ट करने के लिए।
SELECT column_list_please
FROM dbo.Product -- dbo prefix please
ORDER BY
CASE WHEN @sortDir = 'asc' AND @sortOrder = 'name' THEN name END,
CASE WHEN @sortDir = 'asc' AND @sortOrder = 'created_date' THEN created_date END,
CASE WHEN @sortDir = 'desc' AND @sortOrder = 'name' THEN name END DESC,
CASE WHEN @sortDir = 'desc' AND @sortOrder = 'created_date' THEN created_date END DESC;
एक यकीनन आसान समाधान (विशेषकर यदि यह अधिक जटिल हो जाता है) गतिशील SQL का उपयोग करना है। SQL इंजेक्शन को विफल करने के लिए आप मानों का परीक्षण कर सकते हैं:
IF @sortDir NOT IN ('asc', 'desc')
OR @sortOrder NOT IN ('name', 'created_date')
BEGIN
RAISERROR('Invalid params', 11, 1);
RETURN;
END
DECLARE @sql NVARCHAR(MAX) = N'SELECT column_list_please
FROM dbo.Product ORDER BY ' + @sortOrder + ' ' + @sortDir;
EXEC sp_executesql @sql;
गतिशील एसक्यूएल के लिए एक और प्लस, इसके बारे में फैले सभी भय-भ्रम के बावजूद:आप एक एकल योजना के बजाय प्रत्येक प्रकार की भिन्नता के लिए सबसे अच्छी योजना प्राप्त कर सकते हैं, जो पहले उपयोग करने के लिए आपके द्वारा किए गए किसी भी प्रकार की भिन्नता को अनुकूलित करेगा। हाल ही में मेरे द्वारा चलाए गए प्रदर्शन की तुलना में इसने सार्वभौमिक रूप से सर्वश्रेष्ठ प्रदर्शन किया:
http://sqlperformance.com/conditional-order-by