Skip to Main Content

SQL & PL/SQL

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

ORA-32031: illegal reference of a query name in WITH clause

3743447Apr 4 2020 — edited Apr 7 2020

I am trying to create CTE with Oracle 10g and unfortunately getting the below error:

ORA-32031: illegal reference of a query name in WITH clause

Is there any way to resolve or alternate solution to make it work? (Unfortunately I've to use the old version) My logic that worked in SQL Server and here is the working sample for reference - https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=460b995ca1b02795ef591ab5c9d1c021

Logic: Checking occurrence of 8 or sum of 8 once for an id. So for 1122, first four 2 returns 8 and updating those rows that matches the criteria. Basically I am checking the sum of 8 or value 8 at the first occurrence of an id. Basically I am having issues converting the below recursive CTE in Oracle 10g and the update at the end:

with Q1 as

(

    select *, row_number() over (partition by id order by storedate) as n

    from @tab

),

Q2 as

(

    select Q1.id, [value] as s, n as m, format(n, '000') as p

    from Q1

    where [value] <= 8

    union all

    select Q1.id, Q1.[value] + s, Q1.n, Q2.p + ',' + format(Q1.n, '000')

    from Q1

    inner join Q2 on Q2.id = Q1.id and Q1.n > Q2.m and Q1.[value] + s <= 8

),

Q3 as

(

    select id, min(p) as p

    from Q2

    where s = 8

    group by id

)

select * from Q3;

update Q1

set [value] = 0, info = ''

from Q1

inner join Q3 on Q3.id = Q1.id

where Q1.n in (select [value] from string_split(Q3.p, ',') )

Though I tried a bit with Connect By (A suggestion by one of my friend) as there is no option for recursive CTE in the older version but that doesn't return the expected output:

CREATE TABLE SAMPLE_TEST_2020
(
  ID VARCHAR2
(20 BYTE)
, STOREDATE DATE
, VALUE NUMBER
, INFO VARCHAR2(20 BYTE)
)

ID     STOREDATE  VALUE INFO
4466   01-JAN-20  2     DONE
4466   02-JAN-20  2     DONE
4466   03-JAN-20  2     DONE
4466   04-JAN-20  2     DONE

4466   05-JAN-20  8     DONE

4466   06-JAN-20  6     DONE

1122   01-JAN-20  2     DONE
1122   02-JAN-20  2     DONE
1122   03-JAN-20  2     DONE
1122   04-JAN-20  6     DONE

with rws as (
 
select m.id, m.value,
  row_number
() over (
  
partition by id order by storedate
  
) as rn
 
from sample_test_2020 m
), tree as (
 
select id, lpad ( rn, 3, '0' ) rn, prior value + value v
 
from  rws
 
start with value <= 8
 
connect by prior rn < rn
 
and prior id = id
 
and prior value + value <= 8
)
 
select id, min ( rn ) || ',' || max ( rn ) p

  from  tree
 
group  by id;

But the above query returns the following output:

ID     P 
1122   001,006  
4466   001,004

Expected Output:

ID     P 
1122   001,002,003,004 //The same logic for this one as below   
4466   001,004 //For id 4466, 001 is the row value 2 and 004 is row value 6, together they return value 8

This post has been answered by Paulzip on Apr 5 2020
Jump to Answer
Comments
Post Details
Added on Apr 4 2020
24 comments
2,017 views