I am experimenting with a recursive CTE to split a string into multiple values. The data is then inserted into another table.
The following works in PostgreSQL:
CREATE TABLE test(data varchar(255));
WITH RECURSIVE
cte(genres) AS (SELECT 'apple,banana,cherry,date'),
split(genre,rest,genres) AS (
SELECT '', genres||',',genres FROM cte
UNION ALL
SELECT
substring(rest,0,position(',' IN rest)),
substring(rest,position(',' IN rest) 1),
genres
FROM split WHERE rest<>''
)
INSERT INTO test(data)
SELECT genre
FROM split;
However, the Oracle version:
CREATE TABLE test(data varchar(255));
WITH
cte(genres) AS (SELECT 'apple,banana,cherry,date' FROM dual),
split(genre,rest,genres) AS (
SELECT '', genres||',',genres FROM cte
UNION ALL
SELECT
substr(rest,1,instr(rest,',')-1),
substr(rest,instr(rest,',') 1),
genres
FROM split WHERE rest IS NOT NULL
)
INSERT INTO test(data)
SELECT genre
FROM split WHERE genre IS NOT NULL;
gives me the error message:
ORA-00928: missing SELECT keyword.
Now I’m pretty sure that I’ve got one, there between the INSERT
and the following FROM
.
If you comment out the INSERT
, the rest of it will give the results. Elsewhere, I know that a simple INSERT … SELECT
does work.
Is it something to do with the recursive CTE? How can I get this to work properly using a standard recursive CTE?
Using Oracle 18c in a Docker image. There is a fiddle here: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=d24f3105634933af1b7072bded1dacdf .
CodePudding user response:
An INSERT-SELECT means "INSERT" command first, then the SELECT part, and the WITH is part of the SELECT not the insert.
SQL> create table t ( x int );
Table created.
SQL> with blah as ( select 1 c from dual)
2 insert into t
3 select * from blah;
insert into t
*
ERROR at line 2:
ORA-00928: missing SELECT keyword
SQL> insert into t
2 with blah as ( select 1 c from dual)
3 select * from blah;
1 row created.