Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

Oracle दिनांक DST की वजह से टूटी हुई तुलना

इस त्रुटि से बचने के लिए, जहां क्लॉज में एक टाइमस्टैम्प प्रकार (टाइमज़ोन के बिना टाइमस्टैम्प) में अभिव्यक्ति के एक स्पष्ट कलाकार का उपयोग करने पर विचार करें:

select * 
from MY_TABLE T
where T.MY_TIMESTAMP >= cast(CURRENT_TIMESTAMP - interval '1' hour As timestamp );

वैकल्पिक रूप से आप सत्र समय क्षेत्र को स्पष्ट रूप से सेट कर सकते हैं, उदाहरण के लिए '-05:00' - न्यूयॉर्क मानक (सर्दियों) समय के लिए,
ALTER SESSION time_zone ='-05:00' , या सभी क्लाइंट के वातावरण में ORA_SDTZ पर्यावरण चर सेट करके,
विवरण के लिए यह लिंक देखें:http://docs.oracle.com/cd/E11882_01/server.112/e10729/ch4datetime.htm#NLSPG263

लेकिन यह इस बात पर भी निर्भर करता है कि वास्तव में तालिका में टाइमस्टैम्प कॉलम में संग्रहीत है, उदाहरण के लिए क्या टाइमस्टैम्प 2014-07-01 15:00:00 वास्तव में प्रतिनिधित्व करता है, क्या यह "सर्दियों का समय" या "गर्मी का समय" है?

CURRENT_TIMESTAMP फ़ंक्शन टाइम ज़ोन के साथ डेटाटाइप टाइमस्टैम्प का मान देता है
यह लिंक देखें:http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions037.htm

जबकि टाइमस्टैम्प और तिथियों की तुलना करते हुए, Oracle अप्रत्यक्ष रूप से डेटा को अधिक सटीक डेटा प्रकार सत्र समय क्षेत्र का उपयोग करके परिवर्तित करता है!
यह लिंक देखें --> http://docs.oracle.com/cd/E11882_01/server.112/e10729/ch4datetime.htm#NLSPG251

हमारे विशेष मामले में, Oracle कास्ट करता है टाइमस्टैम्प समय क्षेत्र के साथ टाइमस्टैम्प . पर कॉलम type.

Oracle क्लाइंट परिवेश से एक सत्र समय क्षेत्र निर्धारित करता है।
आप इस क्वेरी का उपयोग करके वर्तमान सत्र समय क्षेत्र निर्धारित कर सकते हैं:

select sessiontimezone from dual;

उदाहरण के लिए मेरे पीसी (विन 7) पर, जब विकल्प ""डेलाइट सेविंग टाइम के लिए स्वचालित रूप से घड़ी समायोजित करें" चेक किया जाता है, तो यह क्वेरी वापस आती है (SQLDeveloper के तहत):

SESSIONTIMEZONE                                                           
---------------
Europe/Belgrade 


जब मैं विंडोज़ में इस विकल्प को अनचेक करता हूं और फिर SQLDeveloper को पुनरारंभ करता हूं, तो यह देता है:

SESSIONTIMEZONE                                                           
---------------
+01:00     

पूर्व सत्र समयक्षेत्र एक क्षेत्र नाम वाला समयक्षेत्र है, जिसके लिए Oracle दिनांक गणना में इस क्षेत्र के लिए डेलाइट सेविंग टाइम नियमों का उपयोग करता है:

alter session set time_zone = 'Europe/Belgrade';
select cast( timestamp '2014-01-29 01:30:00' as timestamp with time zone ) As x,
       cast( timestamp '2014-05-29 01:30:00' as timestamp with time zone ) As y
from dual;

session SET altered.
X                            Y                          
---------------------------- ----------------------------
2014-01-29 01:30:00 EUROPE/B 2014-05-29 01:30:00 EUROPE/B 
ELGRADE                      ELGRADE       


बाद का समय क्षेत्र एक निश्चित ऑफसेट "+01:00" (हमेशा "शीतकालीन समय") का उपयोग करता है, और Oracle इसके लिए कोई DST नियम लागू नहीं करता है, यह केवल निश्चित ऑफसेट जोड़ता है।

alter session set time_zone = '+01:00';
select cast( timestamp '2014-01-29 01:30:00' as timestamp with time zone ) As x,
       cast( timestamp '2014-05-29 01:30:00' as timestamp with time zone ) As y
from dual;

session SET altered.
X                            Y                          
---------------------------- ----------------------------
2014-01-29 01:30:00 +01:00   2014-05-29 01:30:00 +01:00  

कृपया ध्यान दें, जिज्ञासा के लिए, कि Y उपरोक्त में परिणाम दो अलग-अलग समय का प्रतिनिधित्व करते हैं !!!
014-05-29 01:30:00 यूरोप/बेलग्रेड के समान नहीं है:2014-05-29 01:30:00 +01:00

लेकिन वास्तव में यह:
014-05-29 01:30:00 यूरोप/बेलग्रेड के बराबर है:2014-05-29 01:30:00 +02:00

उपरोक्त केवल आपको इस बात से अवगत कराने के लिए है कि "बॉक्स अन-चेकिंग" आपके प्रश्नों को कितनी सरलता से प्रभावित कर सकता है, और जब उपयोगकर्ता शिकायत करते हैं कि "इस क्वेरी ने जनवरी में ठीक काम किया, लेकिन दिया जुलाई में गलत परिणाम"।

और अभी भी ORA-01878 के विषय पर - मान लें कि मेरा सत्र यूरोप/वारसॉ है और मेरी तालिका में यह टाइमस्टैम्प है (बिना समय क्षेत्र के)

'TIMESTAMP'2014-03-30 2:30:00'

ध्यान दें कि मेरे क्षेत्र में 2014 वर्ष में, डीएसटी परिवर्तन, 30 मार्च को दोपहर 2:00 बजे होता है। 2:00 से 3:00 बजे तक आगे;)

alter session set time_zone = 'Europe/Warsaw';
select cast( TIMESTAMP'2014-03-30 2:30:00' as timestamp with time zone ) As x
from dual;

SQL Error: ORA-01878: podane pole nie zostało znalezione w dacie-godzinie ani w interwale
01878. 00000 -  "specified field not found in datetime or interval"
*Cause:    The specified field was not found in the datetime or interval.
*Action:   Make sure that the specified field is in the datetime or interval.

Oracle जानता है, कि यह टाइमस्टैम्प मेरे क्षेत्र में मान्य नहीं है डीएसटी नियमों के अनुसार, क्योंकि 30 मार्च को 2:30 बजे कोई समय नहीं है - 2:00 बजे घड़ी को 3:00 बजे स्थानांतरित कर दिया जाता है, और 2:30 बजे कोई समय नहीं होता है। इसलिए Oracle त्रुटि ORA-01878 फेंकता है।

हालाँकि यह क्वेरी पूरी तरह से ठीक काम करती है:

alter session set time_zone = '+01:00';
select cast( TIMESTAMP'2014-03-30 2:30:00' as timestamp with time zone ) As x
from dual;

session SET altered.
X                          
----------------------------
2014-03-30 02:30:00 +01:00 

और यह इस त्रुटि का एक कारण है - आपकी तालिका में 2014-03-09 2:30 जैसे टाइमस्टैम्प हैं या तो (न्यूयॉर्क के लिए, जहां डीएसटी बदलाव 9 मार्च और 2 नवंबर को होते हैं), और Oracle नहीं जानता कि उन्हें टाइमस्टैम्प (TZ के बिना) से TZ के साथ टाइमस्टैम्प में कैसे बदला जाए।

अंतिम प्रश्न - >= के साथ क्वेरी क्यों काम नहीं करता है, लेकिन <= . के साथ क्वेरी ठीक काम करता है ?

वे काम करते हैं/काम नहीं करते, क्योंकि SQLDeveloper केवल पहली 50 पंक्तियां देता है (शायद 100? यह सेटिंग्स पर निर्भर करता है)। क्वेरी पूरी तालिका को नहीं पढ़ती है, यह तब रुक जाती है जब पहली 50 (100) पंक्तियाँ लाई जाती हैं।
उदाहरण के लिए "कार्यशील" क्वेरी को इसमें बदलें:

select sum( EXTRACT(HOUR from MY_TIMESTAMP) ) from MY_TABLE 
where MY_TIMESTAMP <= (CURRENT_TIMESTAMP - interval '1' hour );

यह क्वेरी को तालिका में सभी पंक्तियों को पढ़ने के लिए मजबूर करता है, और त्रुटि दिखाई देगी, मैं 100% निश्चित हूं।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. जावा संग्रहित प्रक्रिया बनाम पीएल/एसक्यूएल संग्रहित प्रक्रिया

  2. कुछ क्षेत्रों में मुद्रा चिह्न £, $ जोड़ें ORACLE

  3. ओरेकल एसक्यूएल घंटे एचएच में तिथियों के बीच अंतर:एमएम:एसएस

  4. .net . के लिए वैकल्पिक Oracle ड्राइवर

  5. संक्षेप में हल्का