給Oracle添加split和splitstr函數


最近項目中有很多需要做批量操作的需求,客戶端把一組逗號分隔的ID字符串傳給數據庫,存儲過程就需要把它們分割,然后逐個處理。

以往的處理方式有如下幾種:

1、在存儲過程內寫循環,逐個分析字符串中的ID,然后逐個處理。缺點:循環一次處理一個,如果每次判斷都很多,效率將很受影響。適合每次處理要做單獨判斷的情況。

2、使用臨時表,先調用一個存儲過程將ID拆分並插入到臨時表中,然后結合臨時表可以寫SQL一次處理多筆。缺點:需要插臨時表,效率不高,數據量越大影響越嚴重。

以前的項目用的最多的還是第2中方式,畢竟方便,且效率比第1種好。 

現在項目中用到了很多很多的批量操作,很多的重復代碼讓我不厭其煩。忽然想到,.Net和JS中都有split類似的函數,拆分字符串很方便,oracle中要是也有這樣的功能該多好呀。

多方查找資料發現,給oracle添加split函數是完全可以實現的,避免了插入臨時表,所以效率比上面的第2中方法效率高很多。

后來我還添加了splitstr函數,可以很方便獲取字符串中的指定節點。 

有了這兩個函數,處理批量操作,真是如虎添翼,效率倍增,嘿嘿……

好了,閑話少說,上代碼!如有不妥之處,請各位前輩博友斧正。

 1  /*
 2   * Oracle 創建 split 和 splitstr 函數
 3    */
 4 
 5  /*  創建一個表類型  */
 6  create  or  replace type tabletype  as  table  of  VARCHAR2( 32676)
 7  /
 8 
 9  /*  創建 split 函數  */
10  CREATE  OR  REPLACE  FUNCTION split (p_list CLOB, p_sep  VARCHAR2 : =  ' , ')
11     RETURN tabletype
12    PIPELINED
13  /* *************************************
14   * Name:        split
15   * Author:      Sean Zhang.
16   * Date:        2012-09-03.
17   * Function:    返回字符串被指定字符分割后的表類型。
18   * Parameters:  p_list: 待分割的字符串。
19                  p_sep: 分隔符,默認逗號,也可以指定字符或字符串。
20   * Example:     SELECT *
21                    FROM users
22                   WHERE u_id IN (SELECT COLUMN_VALUE
23                                    FROM table (split ('1,2')))
24                  返回u_id為1和2的兩行數據。
25   ************************************* */
26  IS
27    l_idx    PLS_INTEGER;
28    v_list    VARCHAR2 ( 32676) : = p_list;
29  BEGIN
30    LOOP
31       l_idx   : = INSTR (v_list, p_sep);
32 
33        IF l_idx  >  0
34        THEN
35           PIPE ROW (SUBSTR (v_list,  1, l_idx  -  1));
36          v_list   : = SUBSTR (v_list, l_idx  + LENGTH (p_sep));
37        ELSE
38           PIPE ROW (v_list);
39           EXIT;
40        END  IF;
41     END LOOP;
42  END;
43  /
44 
45  /*  創建 splitstr 函數  */
46  CREATE  OR  REPLACE  FUNCTION splitstr ( str  IN CLOB,
47                                        i    IN  NUMBER : =  0,
48                                        sep  IN  VARCHAR2 : =  ' , '
49 )
50     RETURN  VARCHAR2
51  /* *************************************
52   * Name:        splitstr
53   * Author:      Sean Zhang.
54   * Date:        2012-09-03.
55   * Function:    返回字符串被指定字符分割后的指定節點字符串。
56   * Parameters:  str: 待分割的字符串。
57                  i: 返回第幾個節點。當i為0返回str中的所有字符,當i 超過可被分割的個數時返回空。
58                  sep: 分隔符,默認逗號,也可以指定字符或字符串。當指定的分隔符不存在於str中時返回sep中的字符。
59   * Example:     select splitstr('abc,def', 1) as str from dual;  得到 abc
60                  select splitstr('abc,def', 3) as str from dual;  得到 空
61   ************************************* */
62  IS
63    t_i        NUMBER;
64    t_count    NUMBER;
65    t_str      VARCHAR2 ( 4000);
66  BEGIN
67     IF i  =  0
68     THEN
69       t_str   : =  str;
70    ELSIF INSTR ( str, sep)  =  0
71     THEN
72       t_str   : = sep;
73     ELSE
74        SELECT  COUNT (  * )
75        INTO t_count
76        FROM  table (split ( str, sep));
77 
78        IF i  <= t_count
79        THEN
80           SELECT  str
81           INTO t_str
82           FROM ( SELECT ROWNUM  AS item, COLUMN_VALUE  AS  str
83                 FROM  table (split ( str, sep)))
84           WHERE item  = i;
85        END  IF;
86     END  IF;
87 
88     RETURN t_str;
89  END;
90  /

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM