Den forespørgsel, du forsøger at komme til:
SELECT id, split_function(city) FROM COMMA_SEPERATED
vil ikke virke, fordi du forsøger at returnere flere rækker for hver kilderække. Du skal desværre gøre det lidt mere kompliceret end som så.
Hvis målet er at skjule opdelingsmekanismen, så er det tætteste jeg kan komme i tanke om at oprette en funktion, som returnerer en samling af strenge, som kunne være pipelinet :
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;
/
Dit foreslåede opkald vil så give dig én række pr. ID med en samling:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
hvilket ikke helt er, hvad du ønsker; men du kan bruge et tabelsamlingsudtryk og cross-join til at konvertere til flere rækker i stedet:
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
Det er ikke så simpelt, som du håbede på, men det er uden tvivl stadig bedre end at kryds-joining til xmltable()
, især hvis du vil genbruge den opdelingslogik/funktion flere steder, samt skjule detaljerne om, hvordan opdelingen udføres - hvilket ville lade dig ændre mekanismen nemt, hvis du ville, f.eks. at bruge et mere almindeligt regulært udtryk til at foretage opdelingen.