Dotaz, ke kterému se pokoušíte dostat:
SELECT id, split_function(city) FROM COMMA_SEPERATED
nebude fungovat, protože se pokoušíte vrátit více řádků pro každý zdrojový řádek. Bohužel to musíte udělat trochu složitější.
Pokud je cílem skrýt rozdělovací mechanismus, pak nejbližší, co mě napadá, je vytvořit funkci, která vrací kolekci řetězců, což by mohlo být propojeno :
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;
/
Váš navrhovaný hovor vám pak poskytne jeden řádek na ID s kolekcí:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
což není úplně to, co chcete; ale místo toho můžete použít výraz kolekce tabulek a křížové spojení pro převod do více řádků:
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
To není tak jednoduché, jak jste doufali, ale je to pravděpodobně stále lepší než křížové připojení k xmltable()
, zejména pokud chcete znovu použít logiku/funkci rozdělení na více místech a také skrýt podrobnosti o tom, jak se rozdělení provádí - což vám umožní snadno změnit mechanismus, pokud chcete, např. k rozdělení použijte běžnější regulární výraz.