額..悲劇了.真的是悲劇了.
有這么一個問題被問到了,"表中某個字段的值是用分號隔開的,我要分別取出來,SQL怎么寫啊?".我開始沒怎么注意,以為很是容易.心想oracle這個死貴但又牛比的產品肯定會提供現成的方法來處理這樣的用戶需求,就回復給人說:"使用oracle的字符串分隔函數".還信誓旦旦的要寫個例子出來.原本以為幾分鍾的事情,但是..杯具接着就來了.沒有現成的函數,我擦...郁悶..沒面子啊....羞愧難當啊.上面是題外話,也順便說明了我這個問題的由來.如何解決呢?本着大哥一貫的做事風格..必須解決之...
由於對oracle了解十分有限,很多功能特性都沒有時間耐下心來研讀(真是罪過啊~~)自己寫還是很費時的,憋了一會沒憋出來.只有google了.找了個能夠滿足需求的例子,分析一下就能夠滿足需要了.
實現如下:
--創建一個type,便於在后面自定義的split函數中使用
create or replace type type_split as table of varchar2(500);
--創建自定義函數split,
--本函數包含兩個參數變量p_list需要處理的字符串,和p_sep分隔符
--函數返回類型為上面自定義的type_split,
--使用pipelined 的function為了提高效率,不用等所有的數據都處理完成了才返回客戶端,它是邊處理邊返回.適用於大數據量的交互
--邏輯:循環需要處理的字符串v_list,每次循環獲取分隔符的位置,根據位置截取v_list,推出循環的條件是:需要處理的字符串v_list中已經沒有分隔符存在(這個邏輯是否跟java中string里面的split()一樣呢?這個問題有待驗證啊...還是高級語言好使啊 高效啊~~)
create or replace function split
(
p_list varchar2,
p_sep varchar2 := ';'
) return type_split pipelined
is
l_idx pls_integer;
v_list varchar2(500) := p_list;
begin
loop
l_idx := instr(v_list,p_sep);
if l_idx > 0 then
pipe row(substr(v_list,1,l_idx-1));
v_list := substr(v_list,l_idx+length(p_sep));
else
pipe row(v_list);
exit;
end if;
end loop;
return;
end split;
--測試 語句
select * from table(split('121212;dfd;dfd;vvv;llll;對方答復',';'));
從問題的角度來說 上面已經解決了.但從這事情來看,我還是暴漏了很多的不足.知識盲點總會是有的.但遇到知識盲點采取何種策略解決,很明顯目前我擁有的解決方案不盡如人意啊.這點還需加強一下.具體該如何做呢?馬上就下班了 剛好趁着這個點總結一下,哄哄~~.最重要的一點:學會解決問題,媽呀 這個話太大了..自己說出來都有些害怕.哈哈,還是需要靜心,仔細的 不急不躁的一點點的解決,寫程序嘛.就要耐得住性子.還應該做到多思考,長琢磨.這點就不說了,要不然真的成為碼農了.最后又時間 要多看書,從更加宏觀的方法去把握技術的體系,要有一個堅實的理論基礎才行呢.就先寫這么多吧.