對於oracle;在字串處理時;經常會遇到字串分割的問題;可惜SQL中沒有split函式;這個倒是挺困擾我們寫sql的。對此;我來說說這字串分割。
例如對欄位str中一條資料是'120-mm-265';我要取到其中的mm。若對其它語言之間;例如awk。split("120-mm-265",a,"-");print a[2];就搞定了。
1. 可能大家覺得很簡單;我用substr(str,5,2)就行了。可惜你把問題想得太簡單了。我們處理是多條資料;而不是一條資料。若它下面一條的資料是'12-oko-45'。這樣的話 。那就是ko;並非我們想要的oko
2. 可能大家還會想到instr函式。這個函式是可以解決的。但是還是要借用sbustr函式
SELECT substr('120-mm-265',
instr('120-mm-265', '-', 1, 1) + 1,
instr('120-mm-265', '-', 1, 2) -
(instr('120-mm-265', '-', 1, 1) + 1))
FROM dual
這樣的結果大家可以接受嗎?
3. 兩年前;我想到一種方法。就是借用ltrim,rtrim函式。由於前面和後面都是數字
SELECT rtrim(ltrim('120-mm-265', '0123456789-'), '0123456789-')
FROM dual;
這種情況是可以實現。但是這種情況呢'20m-mm-f25'。這種實現擴充套件性不強。所以這種也不考慮。
4. 由於上面3種寫法;大家能接受嗎?不能接受;那就進入高階寫法。
使用正則函式。
SELECT regexp_substr('120-mm-265', '[^-]+', 1, 2)
FROM dual; --推薦這種。
SELECT regexp_replace('120-mm-265', '(.*)-(.*)-(.*)', '\2')
FROM dual;
我相信這兩種方法應該可以讓你滿意;若還不能讓你滿意;那就是正則函式是10g版本才有的。若低於10g版本,那該怎麼辦?那就看看下面吧
5. 自定義函式split。oracle不提供內建函式split。那麼就自定義。
CREATE OR REPLACE FUNCTION splitstr
(
v_desc IN VARCHAR,
v_icount IN NUMBER
) RETURN VARCHAR IS
v_result VARCHAR(20);
v_pos NUMBER(2);
v_str VARCHAR(1000);
v_count_2 NUMBER(2);
v_word VARCHAR(20);
BEGIN
v_result := '';
v_str := v_desc || ',,,';
v_count_2 := 0;
v_pos := instr(v_str, ',');
WHILE v_pos > 1
LOOP
v_count_2 := v_count_2 + 1;
v_word := substr(v_str, 1, v_pos - 1);
IF v_icount = v_count_2 THEN
v_result := v_word;
RETURN v_result;
ELSE
IF v_icount < v_count_2 THEN
RETURN '';
ELSE
IF v_str <> ',' THEN
v_str := substr(v_str, v_pos + 1);
v_pos := instr(v_str, ',');
END IF;
END IF;
END IF;
END LOOP;
RETURN v_result;
END;
SELECT splitstr(replace('120-mm-265','-',','),2) from dual
這樣執行就ok
若還有好點的方法到時候再補充;若大家有好點的方法也可以補充。