A consulta que você está tentando acessar:
SELECT id, split_function(city) FROM COMMA_SEPERATED
não funcionará, porque você está tentando retornar várias linhas para cada linha de origem. Você tem que torná-lo um pouco mais complicado do que isso, infelizmente.
Se o objetivo é ocultar o mecanismo de divisão, o mais próximo que consigo pensar é criar uma função que retorne uma coleção de strings, que poderia ser encaminhado :
create or replace function split_function (p_string varchar2)
return sys.odcivarchar2list pipelined as
begin
for r in (
select result
from xmltable (
'if (contains($X,",")) then ora:tokenize($X,"\,") else $X'
passing p_string as x
columns result varchar2(4000) path '.'
)
)
loop
pipe row (trim(r.result));
end loop;
end split_function;
/
Sua chamada proposta forneceria uma linha por ID com uma coleção:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
que não é bem o que você quer; mas você pode usar uma expressão de coleção de tabelas e junção cruzada para converter em várias linhas:
select cs.id, t.column_value as city
from comma_seperated cs
cross join table(split_function(cs.city)) t;
ID CITY
---------- ------------------------------
1 CHENNAI
1 HYDERABAD
1 JABALPUR
2 BHOPAL
2 PUNE
db<>demonstração do violino .
Isso não é tão simples quanto você esperava, mas é sem dúvida ainda melhor do que a junção cruzada com o
xmltable()
, especialmente se você quiser reutilizar essa lógica/função de divisão em vários lugares, bem como ocultar os detalhes de como a divisão é feita - o que permitiria alterar o mecanismo facilmente se você quisesse, por exemplo para usar uma expressão regular mais comum para fazer a divisão.