取得しようとしているクエリ:
SELECT id, split_function(city) FROM COMMA_SEPERATED
ソース行ごとに複数の行を返そうとしているため、機能しません。残念ながら、それよりも少し複雑にする必要があります。
分割メカニズムを非表示にすることが目標である場合、私が考えることができる最も近い方法は、文字列のコレクションを返す関数を作成することです。これは、パイプライン :
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;
/
提案された呼び出しでは、コレクションを含むIDごとに1つの行が提供されます:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
これはあなたが望むものではありません。ただし、代わりにテーブルコレクション式と相互結合を使用して複数の行に変換できます:
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
これは思ったほど簡単ではありませんが、xmltable()
に相互結合するよりも間違いなく優れています。 特に、その分割ロジック/関数を複数の場所で再利用したり、分割の実行方法の詳細を非表示にしたりする場合は、必要に応じてメカニズムを簡単に変更できます。より一般的な正規表現を使用して分割を実行します。