• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 給Oracle添加split和splitstr函數

    發表于:2012-11-13來源:博客園作者:享受代碼點擊數: 標簽:
    最近項目中有很多需要做批量操作的需求,客戶端把一組逗號分隔的ID字符串傳給數據庫,存儲過程就需要把它們分割,然后逐個處理。 以往的處理方式有如下幾種:

      最近項目中有很多需要做批量操作的需求,客戶端把一組逗號分隔的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 /

    復制代碼

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>