2010-04-06 9 views
5

ओरेकल 11g रिलीज 2 का उपयोग करना, निम्न क्वेरी एक ORA-01,790 देता है: अभिव्यक्ति इसी अभिव्यक्ति के रूप में एक ही डेटाप्रकार होना चाहिए:रिकर्सिव एसक्यूएल देने ORA-01,790

with intervals(time_interval) AS 
(select trunc(systimestamp) 
    from dual 
    union all 
    select (time_interval + numtodsinterval(10, 'Minute')) 
    from intervals 
    where time_interval < systimestamp) 
select time_interval from intervals; 

त्रुटि पता चलता है कि दोनों सबक्वेरी की डेटाप्रकार यूनियन सभी अलग-अलग डेटाटाइप लौट रहे हैं।

भले ही मैं प्रत्येक सबक्वायरीज़ में TIMESTAMP पर जाता हूं, फिर भी मुझे एक ही त्रुटि मिलती है।

मुझे क्या याद आ रही है?

संपादित करें: मैं प्रतिस्थापन से कनेक्ट नहीं ढूंढ रहा हूं।

+0

'time_interval' का प्रकार क्या है और क्यों अपने शीर्षक * रिकर्सिव कहना है *? –

+0

@ पीटर: दृश्य संदर्भ खुद के साथ। यह 11 जीआर 2 में नया है। देखें http://download.oracle.com/docs/cd/E11882_01/server.112/e10881/chapter1.htm#FEATURENO08835 – PenFold

+0

यह देखने में विफल, क्षमा करें। –

उत्तर

6

मेरी राय में, "रिकर्सिव Subquery फैक्टरिंग" है दिनांक या टाइमस्टैम्प कॉलम के साथ प्रश्नों के लिए 11 जी आर 2 में टूटा हुआ।

with test(X) as 
(
    select to_date('2010-01-01','YYYY-MM-DD') from dual 
    union all (
    select (X + 1) from test where X <= to_date('2010-01-10','YYYY-MM-DD') 
) 
) 
select * from test; 

ORA-01790 

उपयोग एक डाली डेटाप्रकार कन्वर्ट करने के लिए:

with test(X) as 
(
    select cast(to_date('2010-01-01','YYYY-MM-DD') as date) from dual 
    union all (
    select (X + 1) from test where X <= to_date('2010-01-10','YYYY-MM-DD') 
) 
) 
select * from test; 

X 
------------------- 
2010-01-01 00:00:00 

1 row selected 

एक तिथि मदद कर रहा है में एक तारीख कास्टिंग, लेकिन जहां अन्य परिणाम हैं? पीछे की ओर गिनती

with test(X) as 
(
    select cast(to_date('2007-01-01','YYYY-MM-DD') as DATE) from dual 
    union all (
    select (X + 1) from test where X <= to_date('2011-01-11','YYYY-MM-DD') 
) 
) 
select * from test 
where rownum < 10; -- important! 

X 
------------------- 
2007-01-01 00:00:00 
2006-12-31 00:00:00 
2006-12-30 00:00:00 
2006-12-29 00:00:00 
2006-12-28 00:00:00 
2006-12-27 00:00:00 
2006-12-26 00:00:00 
2006-12-25 00:00:00 
2006-12-24 00:00:00 

9 rows selected 

:

यह भी बेहतर हो जाता ...

एक और प्रारंभ दिनांक के साथ यह प्रयास करें? क्यूं कर?

अपडेट 14 जनवरी 2014: समाधान के लिए, CTE समाप्ति दिनांक के साथ शुरू करने और इस तरह पीछे की ओर पुनरावर्ती CTE के निर्माण, उपयोग करें:

with test(X) as 
(
    select cast(to_date('2011-01-20','YYYY-MM-DD') as DATE) as x from dual 
    union all (
    select cast(X - 1 AS DATE) from test 
    where X > to_date('2011-01-01','YYYY-MM-DD') 
) 
) 
select * from test 

परिणाम:

|        X | 
|--------------------------------| 
| January, 20 2011 00:00:00+0000 | 
| January, 19 2011 00:00:00+0000 | 
| January, 18 2011 00:00:00+0000 | 
| January, 17 2011 00:00:00+0000 | 
| January, 16 2011 00:00:00+0000 | 
| January, 15 2011 00:00:00+0000 | 
| January, 14 2011 00:00:00+0000 | 
| January, 13 2011 00:00:00+0000 | 
| January, 12 2011 00:00:00+0000 | 
| January, 11 2011 00:00:00+0000 | 
| January, 10 2011 00:00:00+0000 | 
| January, 09 2011 00:00:00+0000 | 
| January, 08 2011 00:00:00+0000 | 
| January, 07 2011 00:00:00+0000 | 
| January, 06 2011 00:00:00+0000 | 
| January, 05 2011 00:00:00+0000 | 
| January, 04 2011 00:00:00+0000 | 
| January, 03 2011 00:00:00+0000 | 
| January, 02 2011 00:00:00+0000 | 
| January, 01 2011 00:00:00+0000 | 

परीक्षण के साथ आयोजित:

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production 
0

मैं यहाँ प्रकार मेल नहीं खाता के बारे में पता नहीं है, लेकिन एक वैकल्पिक पद्धति पूरा करने के लिए मैं क्या लगता है कि आप चाहते हैं (जो 10gr2 में काम करता है) है:

select base_time + numtodsinterval(10*(level-1), 'Minute') 
from (select trunc(systimestamp) base_time from dual) 
connect by base_time + numtodsinterval(10*(level-1), 'Minute') < systimestamp 
+0

धन्यवाद डेव, लेकिन मैं एक समाधान की तलाश में हूं जो क्लीनर रिकर्सिव एसक्यूएल सिंटैक्स का उपयोग करता है। – PenFold

2

विषम - बदतर ks अगर आप के आसपास varchar रों गुजरती हैं और परिवर्तित (नहीं डाली):

WITH intervals(time_interval) AS 
    (SELECT to_char(TRUNC(systimestamp)) 
    FROM dual 
    UNION ALL 
    SELECT to_char(to_timestamp(time_interval) + numtodsinterval(10, 'Minute')) 
    FROM intervals 
    WHERE to_timestamp(time_interval) < systimestamp 
) 
SELECT to_timestamp(time_interval) time_interval 
FROM intervals 
संबंधित मुद्दे