Запрос, который вы пытаетесь получить:
SELECT id, split_function(city) FROM COMMA_SEPERATED
не будет работать, потому что вы пытаетесь вернуть несколько строк для каждой строки источника.Вы должны сделать это немного сложнее, к сожалению.
Если цель состоит в том, чтобы скрыть механизм расщепления, то самое близкое, о чем я могу подумать, - это создать функцию, которая возвращает коллекцию строк, которая может быть 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;
/
Ваш предложенный вызов даст вам одну строку для каждого ID с коллекцией:
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
db <> fiddle demo .
Это не тактак просто, как вы надеялись, но, возможно, все же лучше, чем перекрестное соединение с xmltable()
, особенно если вы хотите повторно использовать эту логику / функцию разделения в нескольких местах, а также скрыть детали того, как выполняется разделение -который позволит вам легко изменить механизм, если вы захотите, например, использовать более распространенное регулярное выражение для разделения.