給Oracle添加split和splitstr函數的方法

來源:互聯網
上載者:User

最近項目中有很多需要做大量操作的需求,用戶端把一組逗號分隔的ID字串傳給資料庫,預存程序就需要把它們分割,然後逐個處理。
以往的處理方式有如下幾種:

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

2、使用暫存資料表,先調用一個預存程序將ID拆分並插入到暫存資料表中,然後結合暫存資料表可以寫SQL一次處理多筆。缺點:需要插暫存資料表,效率不高,資料量越大影響越嚴重。

以前的項目用的最多的還是第2中方式,畢竟方便,且效率比第1種好。
現在項目中用到了很多很多的大量操作,很多的重複代碼讓我不厭其煩。忽然想到,.Net和JS中都有split類似的函數,拆分字串很方便,oracle中要是也有這樣的功能該多好呀。

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

後來我還添加了splitstr函數,可以很方便擷取字串中的指定節點。
有了這兩個函數,處理大量操作,真是如虎添翼,效率倍增,嘿嘿……
好了,閑話少說,上代碼!如有不妥之處,請各位前輩博友斧正。 複製代碼 代碼如下:/*
* Oracle 建立 split 和 splitstr 函數
*/
/* 建立一個表類型 */
create or replace type tabletype as table of VARCHAR2(32676)
/
/* 建立 split 函數 */
CREATE OR REPLACE FUNCTION split (p_list CLOB, p_sep VARCHAR2 := ',')
RETURN tabletype
PIPELINED
/**************************************
* Name: split
* Author: Sean Zhang.
* Date: 2012-09-03.
* Function: 返回字串被指定字元分割後的表類型。
* Parameters: p_list: 待分割的字串。
p_sep: 分隔字元,預設逗號,也可以指定字元或字串。
* Example: SELECT *
FROM users
WHERE u_id IN (SELECT COLUMN_VALUE
FROM table (split ('1,2')))
返回u_id為1和2的兩行資料。
**************************************/
IS
l_idx PLS_INTEGER;
v_list VARCHAR2 (32676) := 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;
END;
/
/* 建立 splitstr 函數 */
CREATE OR REPLACE FUNCTION splitstr (str IN CLOB,
i IN NUMBER := 0,
sep IN VARCHAR2 := ','
)
RETURN VARCHAR2
/**************************************
* Name: splitstr
* Author: Sean Zhang.
* Date: 2012-09-03.
* Function: 返回字串被指定字元分割後的指定節點字串。
* Parameters: str: 待分割的字串。
i: 返回第幾個節點。當i為0返回str中的所有字元,當i 超過可被分割的個數時返回空。
sep: 分隔字元,預設逗號,也可以指定字元或字串。當指定的分隔字元不存在於str中時返回sep中的字元。
* Example: select splitstr('abc,def', 1) as str from dual; 得到 abc
select splitstr('abc,def', 3) as str from dual; 得到 空
**************************************/
IS
t_i NUMBER;
t_count NUMBER;
t_str VARCHAR2 (4000);
BEGIN
IF i = 0
THEN
t_str := str;
ELSIF INSTR (str, sep) = 0
THEN
t_str := sep;
ELSE
SELECT COUNT ( * )
INTO t_count
FROM table (split (str, sep));
IF i <= t_count
THEN
SELECT str
INTO t_str
FROM (SELECT ROWNUM AS item, COLUMN_VALUE AS str
FROM table (split (str, sep)))
WHERE item = i;
END IF;
END IF;
RETURN t_str;
END;
/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.