Kueri yang Anda coba dapatkan:
SELECT id, split_function(city) FROM COMMA_SEPERATED
tidak akan berfungsi, karena Anda mencoba mengembalikan beberapa baris untuk setiap baris sumber. Sayangnya, Anda harus membuatnya sedikit lebih rumit dari itu.
Jika tujuannya adalah untuk menyembunyikan mekanisme pemisahan maka yang paling dekat yang dapat saya pikirkan adalah membuat fungsi yang mengembalikan kumpulan string, yang bisa berupa melalui pipa :
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;
/
Panggilan yang Anda usulkan kemudian akan memberi Anda satu baris per ID dengan koleksi:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
yang tidak sesuai dengan yang Anda inginkan; tetapi Anda dapat menggunakan ekspresi kumpulan tabel dan cross-join untuk mengonversi menjadi beberapa baris sebagai gantinya:
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
Itu tidak sesederhana yang Anda harapkan, tapi bisa dibilang masih lebih baik daripada cross-join ke xmltable()
, terutama jika Anda ingin menggunakan kembali logika/fungsi pemisahan di banyak tempat, serta menyembunyikan detail tentang cara pemisahan dilakukan - yang memungkinkan Anda mengubah mekanisme dengan mudah jika Anda mau, mis. untuk menggunakan ekspresi reguler yang lebih umum untuk melakukan pemisahan.