2011-06-29 19 views
8

मेरे पास SQL ​​सर्वर 2005 में एक SQL क्वेरी है जो टूट रही है जब मैं एक सशर्त आदेश शामिल करता हूं। जब मैं ऑर्डर हटा देता हूं, तो क्वेरी काम करती है। जब मैं स्पष्ट रूप से स्थिति द्वारा आदेश लिखता हूं (उदाहरण के लिए पी। डिस्क्रिप्शन द्वारा ऑर्डर) यह काम करता है। जब मैं द्वारा सशर्त आदेश में शामिल हैं, मैं त्रुटि,एसक्यूएल सर्वर सशर्त आदेश

'Conversion failed when converting character string to smalldatetime data type' 

एसक्यूएल सर्वर मुझे नहीं दिखा रहा है जो कोड की पंक्ति इस त्रुटि के कारण मिलता है। मैं सोच रहा हूं कि मैं इसे कैसे ठीक कर सकता हूं ताकि मैं सशर्त आदेश का उपयोग कर सकूं या समस्या निवारण कर सकूं जो रूपांतरण में विफल हो रहा है।

declare @SearchTerm nvarchar(255) 
declare @SortBy nvarchar(255) 
declare @Months int 
declare @VendorID int 
declare @ProductID int 

set @SearchTerm = 'focus' 
set @SortBy = 'product' 
set @Months = 3 
set @VendorID = null 
set @ProductID = null 

-- This makes it so the @Month will filter by n number of months ago. 
declare @PreviousMonths datetime 
if @Months is null 
    begin 
     set @PreviousMonths = 24 
    end 
else 
    begin 
     set @PreviousMonths = DateAdd(month, [email protected], GetDate()) 
    end 

select 
    a.dsAlertID as AlertID, 
    a.ProductID, 
    v.VendorID, 
    p.Description as ProductName, 
    v.LongName as VendorName, 
    a.Introduction, 
    a.Writeup, 
    a.DateAdded 
from 
    ev_ds_Alerts a 
left outer join 
    tblProducts p on a.ProductID = p.ProductID 
left outer join 
    tblVendors v on v.VendorID = p.VendorID 
where 
    (@SearchTerm is null or (a.Writeup like '% ' + @SearchTerm + '%' or a.Introduction like '% ' + @SearchTerm + '%')) 
    and ((@Months is null) or (@Months is not null and a.DateAdded >= @PreviousMonths)) 
    and ((@VendorID is null) or (@VendorID is not null and v.VendorID = @VendorID)) 
    and ((@ProductID is null) or (@ProductID is not null and p.ProductID = @ProductID)) 
order by 
    case @SortBy 
     when 'product' then p.Description 
     when 'vendor' then v.LongName 
     else a.DateAdded 
    end 

-- order by p.Description or v.LongName works when explicitly writing them out! 
+0

आप n हूँ 'CAST' –

+0

का उपयोग करने के लिए eed डेटा प्रकार कास्ट त्रुटि –

उत्तर

15

पिछले जवाब के अनुसार, कोशिश:

order by case @SortBy when 'product' then p.Description when 'vendor' then v.LongName else convert(VARCHAR(25),a.DateAdded,20)

यह आपको तरह आप चाहते हैं देना चाहिए, के रूप में यह तारीख स्ट्रिंग yyyy-mm-dd hh स्वरूपित होगा: mm: ss।

+1

+1 अच्छा है कि आपको तारीख को प्रारूपित करने के लिए याद किया गया है yyyy-mm-dd hh: mm: ss लगातार क्रम रखने के लिए। –

+0

यह वही था जो मुझे करने की ज़रूरत थी। आपको बहुत - बहुत धन्यवाद! – Halcyon

6

एक ORDER BY में एक CASE अभिव्यक्ति का उपयोग करते समय - डेटा प्रकार लौट आए हमेशा एक ही होना चाहिए।

आप अलग-अलग प्रश्नों को तोड़ने के लिए गतिशील एसक्यूएल या निर्णय तर्क (आईई: IF) का उपयोग किए बिना - जो भी आप चाहते हैं उसे चुनने के लिए चेरी नहीं कर सकते हैं INT, DATETIME, VARCHAR, आदि।

इस उदाहरण में आप DATETIME डेटा प्रकार को उचित VARCHAR में बदलने के लिए CAST/CONVERT का उपयोग कर सकते हैं। लेकिन जब तक आप क्यों नहीं जानते हैं समस्या हो रही है, तो आप भविष्य में इसे फिर से करने की संभावना रखते हैं।

+0

से बचने के लिए स्वतंत्र केस स्टेटमेंट बनाएं, यह समझ में आता है। केस अभिव्यक्ति का उपयोग करने के लिए एक उचित कामकाज क्या होगा? – Halcyon

+0

@ हेलिसन: या तो अलग-अलग प्रश्नों, या गतिशील एसक्यूएल के लिए डेटा प्रकार हैंडलिंग को तोड़ने के लिए 'IF' का उपयोग करें। –

+0

उत्कृष्ट स्पष्टीकरण, लेकिन यह समझाता नहीं है कि ओपी आदेश कैसे कर सकता है। @ नील और @ गीबाथ के अनुसार: कास्टिंग। –

1

कॉलम की सूची में एक न्यूल को अनदेखा किया जाता है, ताकि आप उन्हें प्रकार से नीचे तोड़ सकें;

ORDER BY 
    CASE 
     WHEN @SortBy = 'product' THEN p.Description 
     WHEN @SortBy = 'vendor' THEN v.LongName 
    END 
    , 
    CASE WHEN @SortBy NOT IN ('product', 'vendor') THEN cda.StartDate END 

अंतिम के लिए बिट बदसूरत, बेहतर अगर आप कर सकते हैं;

CASE WHEN @SortBy = '' THEN cda.StartDate END  
+0

मुझे लगता है कि आप अपने उत्तर से दूसरे मामले को हटा सकते हैं और बस स्टार्टडेट जोड़ सकते हैं। पहले मामले में अंतरिक्ष के लिए डिफ़ॉल्ट रूप से एक और का उपयोग करें। मेरा कोड – niktrs

+0

सच देखें, अंतर यह है कि हमेशा दिनांक (अन्य ऑर्डरिंग के बाद) द्वारा ऑर्डर करने पर लागू होता है जो –

11

आप प्रत्येक डेटा प्रकार के लिए एक मामले का उपयोग कर सकते हैं:

order by 
    case @SortBy 
    when 'product' then p.Description 
    when 'vendor' then v.LongName 
    else '' 
    end, 
    case @SortBy 
    when 'added' then a.DateAdded 
    else '1980-01-01' 
    end 
+0

+1 की आवश्यकता हो सकती है या नहीं। मैंने आपका जवाब नहीं देखा था और मैंने कुछ ऐसा लिखा है – niktrs

0

आप प्रदर्शन के बारे में परवाह है, तो आप एक अलग दृष्टिकोण चाहते हो सकता है: 1. एक इनलाइन TVF 2 में अपने चयन लपेटें। दो अलग-अलग चयन करता है का उपयोग करें, ताकि वे दो अलग-अलग योजनाओं प्राप्त कर सकते हैं, संभवतः अधिक कुशल है कि जेनेरिक एक आकार फिट-सब एक योजना है कि तुम अब हो रही है:

IF @SortBy='product' BEGIN 
    SELECT AlertID, 
(snip) 
    FROM MyTvf 
    ORDER BY Description ; 
    RETURN @@ERROR ; 
END 

IF @SortBy='Vendor' BEGIN 
    SELECT AlertID, 
(snip) 
    FROM MyTvf 
    ORDER BY LongName ; 
    RETURN @@ERROR ; 
END 
+0

जो भी डाउनवॉटेड है, क्या आप विस्तारित करना चाहते हैं? –

+0

विचार करने के लिए यह अच्छी सलाह है। – TTT

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