Die Abfrage, zu der Sie gelangen möchten:
SELECT id, split_function(city) FROM COMMA_SEPERATED
funktioniert nicht, da Sie versuchen, mehrere Zeilen für jede Quellzeile zurückzugeben. Du musst es leider etwas komplizierter machen.
Wenn das Ziel darin besteht, den Aufteilungsmechanismus zu verbergen, dann kann ich mir am ehesten vorstellen, eine Funktion zu erstellen, die eine Sammlung von Zeichenfolgen zurückgibt, die pipelined :
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;
/
Ihr vorgeschlagener Aufruf würde Ihnen dann eine Zeile pro ID mit einer Sammlung geben:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
was nicht ganz das ist, was Sie wollen; Sie können jedoch stattdessen einen Tabellenauflistungsausdruck und Cross-Join verwenden, um in mehrere Zeilen zu konvertieren:
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
Das ist nicht so einfach, wie Sie es sich erhofft haben, aber es ist wohl immer noch besser als Cross-Joining mit xmltable()
, insbesondere wenn Sie diese Aufteilungslogik / -funktion an mehreren Stellen wiederverwenden und die Details der Aufteilung ausblenden möchten - wodurch Sie den Mechanismus leicht ändern können, wenn Sie möchten, z. um einen gebräuchlicheren regulären Ausdruck für die Aufteilung zu verwenden.