转自:http://www.cnblogs.com/enjoycode/archive/2012/11/10/oracle_split.html
给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 /