आप जिस क्वेरी तक पहुंचने का प्रयास कर रहे हैं:
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;
/
आपका प्रस्तावित कॉल तब आपको एक संग्रह के साथ प्रति आईडी एक पंक्ति देगा:
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()
में क्रॉस-जॉइनिंग से बेहतर है , विशेष रूप से यदि आप उस विभाजन तर्क/फ़ंक्शन को कई स्थानों पर पुन:उपयोग करना चाहते हैं, साथ ही विभाजन कैसे किया जाता है, इसके विवरण को छिपाना चाहते हैं - जो आपको तंत्र को आसानी से बदलने देगा यदि आप चाहते हैं, उदा। विभाजन करने के लिए अधिक सामान्य नियमित अभिव्यक्ति का उपयोग करने के लिए।