La requête à laquelle vous essayez d'accéder :
SELECT id, split_function(city) FROM COMMA_SEPERATED
ne fonctionnera pas, car vous essayez de renvoyer plusieurs lignes pour chaque ligne source. Vous devez le rendre un peu plus compliqué que cela malheureusement.
Si l'objectif est de masquer le mécanisme de fractionnement, le plus proche auquel je puisse penser est de créer une fonction qui renvoie une collection de chaînes, qui pourrait être en pipeline :
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;
/
Votre proposition d'appel vous donnerait alors une ligne par ID avec une collection :
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
ce qui n'est pas tout à fait ce que vous voulez ; mais vous pouvez utiliser une expression de collection de table et une jointure croisée pour convertir en plusieurs lignes :
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
Ce n'est pas aussi simple que vous l'espériez, mais c'est sans doute encore mieux que la jonction croisée avec le xmltable()
, en particulier si vous souhaitez réutiliser cette logique/fonction de division à plusieurs endroits, ainsi que masquer les détails de la façon dont la division est effectuée - ce qui vous permettrait de modifier facilement le mécanisme si vous le souhaitez, par ex. pour utiliser une expression régulière plus courante pour effectuer le fractionnement.