आपकी एक अंकीय 'युग' संख्या numtodsinterval()
के लिए बहुत बड़ी (या बहुत छोटी) प्रतीत होती है संभालने का कार्य करता है। सेकंड की संख्या के रूप में आप जो सबसे बड़ा मान पास कर सकते हैं वह है 2^31-1:
SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:7.0
SQL> select numtodsinterval(power(2,31), 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
01873. 00000 - "the leading precision of the interval is too small"
*Cause: The leading precision of the interval is too small to store the
specified interval.
*Action: Increase the leading precision of the interval or specify an
interval with a smaller leading precision.
एक युग के रूप में उच्चतम अनुमत संख्या 2038-01-19 03:14:07 का प्रतिनिधित्व करती है। यह वर्ष 2038 की समस्या है , अनिवार्य रूप से।
आप ऋणात्मक संख्या के साथ भी वहां पहुंच सकते हैं:
SQL> select numtodsinterval(-2208988800, 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
-power(2, 31)
. का उपयोग करना एक सकारात्मक मूल्य के लिए लपेटता है, लेकिन उस त्रुटि से कम कुछ भी:
SQL> select numtodsinterval(power(2,31) - 1, 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:7.0
SQL> select numtodsinterval(-power(2,31), 'SECOND') as interval from dual;
INTERVAL
--------------
24855 3:14:8.0
SQL> select numtodsinterval(-power(2,31) - 1, 'SECOND') as interval from dual;
SQL Error: ORA-01873: the leading precision of the interval is too small
आप 1000 से विभाजित कर रहे हैं, इसलिए आपके कॉलम F से K में से एक का मान 2147483647000 से अधिक है। यह खोजने में काफी आसान होना चाहिए, और आप उन कॉलमों में एक चेक बाधा जोड़ने पर विचार कर सकते हैं ताकि उन्हें भी सेट न किया जा सके। उच्च - जांचें कि कॉलम मान 1000 * (power(2, 31) - 1)
से कम या उसके बराबर है . और या तो शून्य से बड़ा, या इससे बड़ा-1000 * (power(2, 31)
भी।
इसका कारण यह है कि जब आपके पास where Col1 = 123
. जैसा फ़िल्टर होता है तो यह त्रुटि नहीं करता है यह है कि आपका फ़िल्टर (विधेय) दृश्य क्वेरी में ऊपर धकेल दिया जाता है और बहुत अधिक मान वाली पंक्तियों का मूल्यांकन नहीं किया जाता है। शायद आपके पास केवल एक ही ऐसा मान हो, और उसका col1
मान नहीं है 123 और इसके col2
मान नहीं है 'एक्सज़'। यदि आप किसी समस्या पंक्ति की पहचान करते हैं और उसके वास्तविक col1
. का उपयोग करके फ़िल्टर करते हैं मान यह अभी भी त्रुटि होगी। बिना फ़िल्टर के सभी पंक्तियों के लिए मूल्यांकन किया जाता है।
आपके पास जो विशिष्ट ऋणात्मक संख्या है वह एक जादुई संख्या प्रतीत होती है:
SQL> select date '1970-01-01' - 2208988800/86400 from dual;
DATE'1970-01-01'-2208988800/86400
---------------------------------
1900-01-01 00:00:00
यदि आप इसे बाहर करना चाहते हैं तो आपको फ़िल्टर जोड़ने के लिए दृश्य परिभाषा को संशोधित करना होगा, उदा:
...
AND tab2.colh > 0
या इसे संभालने के लिए कॉलम एक्सप्रेशन को बदलें, या तो इसकी उपेक्षा करें और इसे शून्य छोड़ दें, या शायद अधिक उपयोगी रूप से उस जादुई तिथि को वापस कर दें:
TO_CHAR(CASE WHEN tab2.colh = -2208988800000 THEN DATE'1900-01-01'
ELSE DATE'1970-01-01' + NUMTODSINTERVAL( tab2.colh / 1000,'SECOND')
END, 'YYYY/MM/DD HH24:MI:SS') AS Col13,
आप अंतराल का उपयोग करने से दिनांक अंकगणित का उपयोग करने के लिए भी बदल सकते हैं:
TO_CHAR(DATE'1970-01-01' + ( tab2.colh / 86400000 ), 'YYYY/MM/DD HH24:MI:SS') AS Col13,
हालांकि, आपको अपनी क्वेरी के बजाय दृश्य परिभाषा को संशोधित करना होगा, जब तक कि colh
चयन सूची में शामिल है (जो ऐसा प्रतीत नहीं होता है), और यहां तक कि अगर आप इसे केवल बाहर कर सकते थे - और यह अभी भी हमेशा त्रुटि से नहीं बच सकता है, इस पर निर्भर करता है कि ऑप्टिमाइज़र ने क्वेरी को कैसे संभाला।