एक वर्ण इनपुट और रिटर्न डेट फॉर्मेट प्राप्त करने के लिए फ़ंक्शन (गलत इनपुट के साथ)


9

मुझे एक स्ट्रिंग चरित्र प्राप्त करने और दिनांक प्रारूप वापस करने के लिए एक फ़ंक्शन लिखने की आवश्यकता है। उदाहरण के लिए इनपुट 20120101 है और मुझे 2012-01-01 की आवश्यकता है। समस्या यह है कि इस "2012ABCD" जैसे कुछ गलत इनपुट हो सकते हैं। उस स्थिति में, मैं चाहता हूं कि फ़ंक्शन 2020-01-01 जैसी निश्चित तारीख को लौटाए। मैंने अब तक जो लिखा है वह है:

Create Function ReturnDate
(@date varchar(8))

Returns date

  as

    begin
       declare @result date

          set @result = (select convert(date , @date,111))
                if(@@ROWCOUNT>0) return @result
                 else return '2020-01-01'
       return @result
    end

यह काम नहीं करता है और मुझे नहीं पता कि दूसरा हिस्सा कैसे संभालना है (जब इनपुट गलत है)।


1
मैं सुझाव दे सकता हूं कि आप "क्वेरी डेटा के साथ लेनदेन-एसक्यूएल पढ़ते हैं" यदि आप बहुत अधिक एसक्यूएल प्रोग्रामिंग कर रहे हैं, तो यह पुस्तक आपको मूल बातें सिखाएगी कि इस तरह से चीजों को कैसे कोडित किया जाए। amazon.com/Exam-70-761-Querying-Data-Transact-SQL-ebook/dp/…
टोनी हिंकल

1
क्या आप yyyymmddप्रारूप के लिए सख्त पार्सिंग चाहते हैं ?
दान गुज़मैन

जवाबों:


9

SQL सर्वर 2012 पर और बाद में आप यह देखने के लिए TRY_CONVERT का उपयोग कर सकते हैं कि क्या इनपुट परिवर्तित किया जा सकता है। यदि यह नहीं हो सकता है, तो एक पूर्ण मान लौटाया जाता है, तब आप परिवर्तित मूल्य या निश्चित तिथि प्राप्त करने के लिए एक COALESCE कर सकते हैं।

begin
   declare @result date
   set @result = COALESCE(TRY_CONVERT(date, @date, 111), '2012-01-01')
   return @result
end

आप TRY CATCHब्लॉक का उपयोग भी कर सकते हैं और ब्लॉक में निर्धारित तारीख को वापस कर सकते हैं CATCH, लेकिन TRY_CONVERT का उपयोग करना सबसे अच्छा अभ्यास है ताकि SQL सर्वर को एक त्रुटि को संभालने की आवश्यकता न हो क्योंकि इसके लिए अधिक समय और संसाधनों की आवश्यकता होती है।

इस प्रकार के कोड के लिए एक फ़ंक्शन क्वेरी में एक ही तर्क का उपयोग करने की तुलना में अधिक ओवरहेड को उकसाएगा, इसलिए यदि इसे हर सेकंड कई बार कहा जा रहा है, तो आप इसके लिए फ़ंक्शन का उपयोग करके महत्वपूर्ण संसाधन चबा सकते हैं। मैं समझता हूं कि इसे कोड के कई टुकड़ों से बुलाया जा सकता है, इसलिए डिफ़ॉल्ट तिथि को बदलने की आवश्यकता होने पर इसे एक फ़ंक्शन बनाने की इच्छा होती है - फिर यह कोई संकलित कोड परिवर्तन नहीं है और बस इस फ़ंक्शन को अपडेट करें।

यदि यह कोड बहुत अधिक चलने वाला है, तो आपको अन्य विकल्पों पर विचार करना चाहिए जो उपयोगकर्ता द्वारा परिभाषित फ़ंक्शन की तुलना में बेहतर प्रदर्शन प्रदान करेंगे। कृपया अपने विकल्पों के अवलोकन के लिए सोलोमन के उत्तर को देखें और इस बारे में और स्पष्टीकरण दें कि आप एक से दूसरे को क्यों चुन सकते हैं।

उदाहरण के लिए, निम्न इनलाइन टेबल-वैल्यू फ़ंक्शन के रूप में लागू किए गए तर्क को दिखाता है, जिसे CROSS APPLYस्थैतिक मूल्य के साथ आपूर्ति नहीं किए जाने की आवश्यकता होती है , लेकिन एक स्केलर UDF की तुलना में बहुत बेहतर प्रदर्शन करता है:

USE [tempdb];

GO
CREATE
OR ALTER -- comment out if using pre-SQL Server 2016 SP1
FUNCTION dbo.ReturnDate (@Date VARCHAR(8))
RETURNS TABLE
AS RETURN
  SELECT ISNULL(TRY_CONVERT(DATE, @Date, 111), '2020-01-01') AS [TheDate];
GO


SELECT *
FROM   (VALUES (1, '20120101'), (2, '2012ABCD')) tab(ID, Input)
CROSS APPLY dbo.ReturnDate(tab.[Input]) dt
/*
ID    Input       TheDate
1     20120101    2012-01-01
2     2012ABCD    2020-01-01
*/

6
लेकिन मैं सिर्फ क्वेरी में TRY_CONVERT का उपयोग करें और ... इस के लिए एक अक्षम अदिश यूडीएफ का उपयोग कर के पूरे विचार छोड़ दिए जाएंगे
हारून बर्ट्रेंड

2
मैं वास्तव में प्रतिनिधि बिंदुओं के बारे में परवाह नहीं करता हूं, इसलिए मैं इस तरह के नुकसान के कारण नहीं कह रहा हूं, लेकिन समुदाय स्पष्ट रूप से सही उत्तर को अस्वीकार करने से लाभ नहीं उठाता है। डाउनवोटिंग के बजाय, एक उत्तर लिखें, मेरा संपादन करें, या क्या बदलना है, इस पर टिप्पणी छोड़ दें। ओपी ने एक समारोह के लिए कहा, और मुझे पता है कि सबसे अच्छा समाधान नहीं हो सकता है, लेकिन यह वह समाधान है जिसे अनुरोध किया गया था।
टोनी हिंकल

3
टोनी: मैंने डाउन-वोट नहीं किया, लेकिन मैं निश्चित रूप से सहमत हूं कि किसी को किसी टिप्पणी में तर्क प्रदान किए बिना या किसी मौजूदा टिप्पणी को वोट नहीं देना चाहिए, जिसमें उनका तर्क भी शामिल है। उस ने कहा: 1)FINALLY टी-एसक्यूएल में कोई ब्लॉक नहीं है (मुझे लगता है कि आपका मतलब है CATCH)। 2) आपको शायद उल्लेख करना चाहिए कि TRY_CONVERT2012 में शुरू हुआ (कुछ लोग पूर्व SQL सर्वर 2012 से अटके हुए हैं)। 3) क्या आपने इनलाइन टीवीएफ पर विचार किया है? वे स्केलर यूडीएफ के समान प्रदर्शन के मुद्दे नहीं हैं।
सोलोमन रटज़की

1
@ टोनीहिंक उन संपादन को बनाने के लिए धन्यवाद, और मेरे SO उत्तर के संदर्भ के लिए :)। फिर भी, मुझे यकीन नहीं है कि कितने पाठक यूडीएफ के तर्क को देखकर और यह समझने में सफल होंगे कि आईटीवीएफ को सफलतापूर्वक लागू करने के लिए इनलाइन टीवीएफ बेहतर होगा। इसलिए, मैंने आगे बढ़कर इसे आपके उत्तर के अंत में जोड़ दिया।
सोलोमन रटज़की

1
@SolomonRutzky धन्यवाद। मैं वास्तव में एक SQL डेवलपर नहीं हूं, जो कि अभी भी मेरे सिर से ऊपर है। शायद मुझे इस तरह से कुछ जवाब नहीं देना चाहिए, लेकिन यह एक जबरदस्त सीखने का अवसर है।
टोनी हिंकल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.