PLSQL開發實現字符串拆分

在應用程序開發中,會出現單選或多選框條件輸入的需求。如輸入框的輸入值為sz,或sz|nj|zj|nt,在SQL中會這樣處理。 select * from tab_1 where col_1=sz ;這是單選框輸入。 select * from tab_1 where col_1 =sz|nj ;這是多選框輸入。 很明顯,多選輸入值不

在應用程序開發中,會出現單選或多選框條件輸入的需求。如輸入框的輸入值為’sz’,或’sz|nj|zj|nt’,在SQL中會這樣處理。

select * from tab_1 where col_1=’sz’ ;這是單選框輸入。

select * from tab_1 where col_1 =’sz|nj’ ;這是多選框輸入。

很明顯,多選輸入值不會查詢出結果。

如何解決這個問題?

有使用動態SQL實現的方法,如拼裝成這樣的SQL語句:select * from tab_1 where col_1 in (‘sz’,’nj’) ;

還有將’sz|nj’拆分插入到臨時表中,再關聯該臨時表實現,如select * from tab_1 where col_1 in (select a from tt);

臨時表涉及到表的創建和維護,還有IO。

我最近想到一個方法:將傳入的字符串以嵌套表類型返回,使用表函數調用,實現這類需求。

函數代碼如下:

1.create or replace function f_get_unitstring(p_str_all in varchar2,??
2.??????????????????????????????????????????? p_str_gap in varchar2)?? 3.? return t_ntb_allstring is? 4.? –create or replace type t_ntb_allstring? is table of varchar2(20);?? 5.? v_ntb_allstring t_ntb_allstring;??
6.?
7.? str_unit varchar2(20);??
8.? str_char varchar2(1);??
9.?
10.? i_str_length number;??
11.? i_str_index? number;??
12.?
13.begin? 14.? /*p_str_city:=’nj~wx~sz~cz~zj~nt~yc~’;*/?? 15.? –p_str_all := ‘1|2|3|’;?? 16.? –p_str_gap := ‘|’;?? 17.?
18.? v_ntb_allstring := t_ntb_allstring();??
19.?
20.? i_str_length := length(p_str_all);??
21.?
22.? i_str_index := 1;??
23.?
24.? while (i_str_index 25.??? str_char := substr(p_str_all, i_str_index, 1);??
26.????
27.??? if (str_char = p_str_gap) then? 28.??????
29.????? if (str_unit is not null) then? 30.??????? v_ntb_allstring.extend(1);??
31.??????? v_ntb_allstring(v_ntb_allstring.count) := str_unit;?? 32.??????? str_unit := null;?? 33.????? end if;?? 34.??????
35.??? else? 36.????? str_unit := str_unit || str_char;??
37.??????
38.????? if (i_str_index = i_str_length) then? 39.??????? v_ntb_allstring.extend(1);??
40.??????? v_ntb_allstring(v_ntb_allstring.count) := str_unit;?? 41.??????? str_unit := ”;?? 42.????? end if;?? 43.??????
44.??? end if;?? 45.????
46.??? i_str_index := i_str_index + 1;??
47.? end loop;?? 48.?
49.? return(v_ntb_allstring);?? 50.end;? 測試如下:

1.SQL> select * from table(f_get_unitstring(‘1aa|2cc|3bb’,’|’));?? 2.???
3.COLUMN_VALUE??
4.——————–?? 5.1aa??
6.2cc??
7.3bb??
8.???
9.SQL>
以上解決方法僅供參數,歡迎交流。

再增加一種方法。

使用pipelined函數也能實現這個需求。但在此處性能優勢不會體現出來,如果您碰巧碰到大數據量如億級別的字符串拆分,該方法就能派上用場。

代碼如下:

1.create or replace function f_get_unitstring(p_str_all in varchar2,??
2.??????????????????????????????????????????? p_str_gap in varchar2)?? 3.? return t_ntb_allstring?? 4.? pipelined is? 5.? –create or replace type t_ntb_allstring? is table of varchar2(20);?? 6.? v_ntb_allstring t_ntb_allstring;??
7.? str_unit varchar2(20);??
8.? str_char varchar2(1);??
9.? i_str_length number;??
10.? i_str_index? number;??
11.begin? 12.? v_ntb_allstring := t_ntb_allstring();??
13.? i_str_length := length(p_str_all);??
14.? i_str_index := 1;??
15.? while (i_str_index 16.??? str_char := substr(p_str_all, i_str_index, 1);????
17.??? if (str_char = p_str_gap) then? 18.????? if (str_unit is not null) then? 19.??????? —? v_ntb_allstring.extend(1);?? 20.??????? —? v_ntb_allstring(v_ntb_allstring.count) := str_unit;?? 21.??????? pipe row(str_unit);??
22.??????? str_unit := null;?? 23.????? end if;?? 24.??? else? 25.????? str_unit := str_unit || str_char;??
26.????? if (str_unit is not null) then? 27.??????? —? v_ntb_allstring.extend(1);?? 28.??????? —? v_ntb_allstring(v_ntb_allstring.count) := str_unit;?? 29.??????? pipe row(str_unit);??
30.??????? str_unit := null;?? 31.????? end if;?? 32.??? end if;?? 33.??? i_str_index := i_str_index + 1;??
34.? end loop;?? 35.? –return(v_ntb_allstring);?? 36.end;?

? 版權聲明
THE END
喜歡就支持一下吧
點贊7 分享