Truy vấn bạn đang cố truy cập:
SELECT id, split_function(city) FROM COMMA_SEPERATED
sẽ không hoạt động, bởi vì bạn đang cố gắng trả lại nhiều hàng cho mỗi hàng nguồn. Thật không may, bạn phải làm cho nó phức tạp hơn một chút.
Nếu mục tiêu là ẩn cơ chế phân tách thì cách gần nhất tôi có thể nghĩ đến là tạo một hàm trả về một tập hợp các chuỗi, có thể là 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;
/
Cuộc gọi được đề xuất của bạn sau đó sẽ cung cấp cho bạn một hàng cho mỗi ID với một bộ sưu tập:
select id, split_function(city) from comma_seperated;
ID SPLIT_FUNCTION(CITY)
---------- -----------------------------------------------------------------
1 ODCIVARCHAR2LIST('CHENNAI', 'HYDERABAD', 'JABALPUR')
2 ODCIVARCHAR2LIST('BHOPAL', 'PUNE')
không hoàn toàn như những gì bạn muốn; nhưng bạn có thể sử dụng biểu thức tập hợp bảng và kết hợp chéo để chuyển đổi thành nhiều hàng thay thế:
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
Điều đó không đơn giản như bạn mong đợi, nhưng được cho là vẫn tốt hơn so với việc tham gia chéo vào xmltable()
, đặc biệt nếu bạn muốn sử dụng lại logic / chức năng phân tách đó ở nhiều nơi, cũng như ẩn chi tiết về cách phân tách được thực hiện - điều này sẽ cho phép bạn thay đổi cơ chế dễ dàng nếu bạn muốn, ví dụ:để sử dụng một biểu thức chính quy phổ biến hơn để thực hiện việc phân tách.