यदि आपके पास सभी संभावित दिनांक स्वरूपों का एक अच्छा विचार है तो क्रूर बल का उपयोग करना आसान हो सकता है:
create or replace function clean_date
( p_date_str in varchar2)
return date
is
l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
('DD-MON-YYYY', 'DD-MON-YY', 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD'
, 'DD/MM/YYYY', 'MM/DD/YYYY', 'YYYY/MM/DD', 'DD/MM/YY', 'MM/DD/YY');
return_value date;
begin
for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
loop
begin
return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
exit;
exception
when others then null;
end;
end loop;
if return_value is null then
raise no_data_found;
end if;
return return_value;
exception
when no_data_found then
raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/
ज्ञात हो कि Oracle के आधुनिक संस्करण दिनांक रूपांतरण के साथ काफी क्षमाशील हैं। इस फ़ंक्शन ने तारीखों को उन स्वरूपों में संभाला जो सूची में नहीं हैं, कुछ दिलचस्प परिणामों के साथ:
SQL> select clean_date('20160817') from dual;
CLEAN_DAT
---------
17-AUG-16
SQL> select clean_date('160817') from dual;
CLEAN_DAT
---------
16-AUG-17
SQL>
जो ढीले डेटा अखंडता नियमों के सामने स्वचालित डेटा सफाई की सीमाओं को प्रदर्शित करता है। पाप की मजदूरी दूषित डेटा है।
@AlexPoole 'RR'
. का उपयोग करने का मामला उठाता है प्रारूप। डेट मास्क के इस तत्व को Y2K क्लज के रूप में पेश किया गया था। यह काफी निराशाजनक है कि हम अभी भी नई सहस्राब्दी में लगभग दो दशकों से इस पर चर्चा कर रहे हैं।
वैसे भी मसला ये है. अगर हम यह स्ट्रिंग '161225'
. डालते हैं आज तक इसकी कितनी सदी है? खैर, 'yymmdd'
देगा 2016-12-15
. काफी उचित, लेकिन '991225'
के बारे में क्या? ? इसकी कितनी संभावना है कि जिस तारीख को हम वास्तव में चाहते हैं वह 2099-12-15
. है ? यह वह जगह है जहां 'RR'
प्रारूप में आ जाता है। मूल रूप से यह सदी को डिफ़ॉल्ट करता है:संख्या 00-49 डिफ़ॉल्ट से 20, 50-99 डिफ़ॉल्ट से 19। यह विंडो Y2K मुद्दे द्वारा निर्धारित की गई थी:2000 में यह अधिक संभावना थी कि '98
निकट भविष्य की तुलना में हाल के अतीत को संदर्भित करता है, और इसी तरह के तर्क '02
. पर लागू होते हैं . इसलिए 1950 का आधा बिंदु। ध्यान दें कि यह एक निश्चित बिंदु . है स्लाइडिंग विंडो नहीं। जैसे-जैसे हम वर्ष 2000 से आगे बढ़ते हैं, धुरी बिंदु उतना ही कम उपयोगी होता जाता है। और जानें।
वैसे भी, मुख्य बिंदु यह है कि 'RRRR' अन्य दिनांक प्रारूपों के साथ अच्छी तरह से नहीं खेलता है:to_date('501212', 'rrrrmmdd') hurls
ओरा-01843:मान्य माह नहीं. So, use
'RR'and test for it before using
'YYYY''। तो मेरा संशोधित कार्य (कुछ व्यवस्थित करने के साथ) इस तरह दिखता है:
create or replace function clean_date
( p_date_str in varchar2)
return date
is
l_dt_fmt_nt sys.dbms_debug_vc2coll := sys.dbms_debug_vc2coll
('DD-MM-RR', 'MM-DD-RR', 'RR-MM-DD', 'RR-DD-MM'
, 'DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-DD-MM');
return_value date;
begin
for idx in l_dt_fmt_nt.first()..l_dt_fmt_nt.last()
loop
begin
return_value := to_date(p_date_str, l_dt_fmt_nt(idx));
exit;
exception
when others then null;
end;
end loop;
if return_value is null then
raise no_data_found;
end if;
return return_value;
exception
when no_data_found then
raise_application_error(-20000, p_date_str|| ' is unknown date format');
end clean_date;
/
मुख्य बिंदु बनी हुई है:जब तारीखों की व्याख्या करने की बात आती है तो हम इस फ़ंक्शन को कितना स्मार्ट बना सकते हैं, इसकी एक सीमा है, इसलिए सुनिश्चित करें कि आप सबसे अच्छे फिट के साथ आगे बढ़ते हैं। यदि आपको लगता है कि आपकी अधिकांश तिथियां दिन-महीने-वर्ष में फिट होती हैं, तो उसे पहले रखें; आपको अभी भी कुछ गलत कास्ट मिलेंगे लेकिन इससे कम अगर आप साल-महीने-दिन के साथ आगे बढ़ते हैं।