La consulta a la que intenta llegar:
SELECT id, split_function(city) FROM COMMA_SEPERATED
no funcionará, porque está intentando devolver varias filas para cada fila de origen. Desafortunadamente, tienes que hacerlo un poco más complicado que eso.
Si el objetivo es ocultar el mecanismo de división, lo más parecido que se me ocurre es crear una función que devuelva una colección de cadenas, que podría ser canalizado :
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;
/
Su llamada propuesta le daría una fila por ID con una colección:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
que no es exactamente lo que quieres; pero puede usar una expresión de colección de tablas y una unión cruzada para convertir en varias filas en su lugar:
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
Eso no es tan simple como esperaba, pero podría decirse que es mejor que unirse de forma cruzada a xmltable()
, particularmente si desea reutilizar esa lógica/función de división en varios lugares, así como ocultar los detalles de cómo se realiza la división, lo que le permitiría cambiar el mecanismo fácilmente si quisiera, p. para usar una expresión regular más común para hacer la división.