首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

给ORACLE平添split和splitstr函数

2013-01-23 
给ORACLE添加split和splitstr函数转自:http://www.cnblogs.com/enjoycode/archive/2012/11/10/oracle_spli

给ORACLE添加split和splitstr函数

转自: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 /

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://hi.baidu.com/zha0ku1/item/0e65dda912f0cdfa14329b0b

oracle中的split 字符串分割函数(绝对可用)

Oracle中的Split函数首先需要定义 2 个类型

1. Row 类型CREATE OR REPLACE TYPE ty_row_str_split ?as object (strValue VARCHAR2 (4000))

2. Table 类型CREATE OR REPLACE TYPE ty_tbl_str_split IS TABLE OF ty_row_str_split

创建函数:

CREATE OR REPLACE FUNCTION fn_split(p_str ? ? ? IN VARCHAR2,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?p_delimiter IN VARCHAR2)

? RETURN ty_tbl_str_split IS

? ?j ? ? ? ? INT := 0;

? ?i ? ? ? ? INT := 1;

? len ? ? ? INT := 0;

? ?len1 ? ? ?INT := 0;

? str ? ? ? VARCHAR2(4000);

? ?str_split ty_tbl_str_split := ty_tbl_str_split();

BEGIN

? len ? := LENGTH(p_str);

? ?len1 := LENGTH(p_delimiter);

?

?

? WHILE j < len LOOP

? ? ?j := INSTR(p_str, p_delimiter, i);

??

? ? IF j = 0 THEN

? ? ? ?j ? ?:= len;

? ? ? str := SUBSTR(p_str, i);

? ? ? ?str_split.EXTEND;

? ? ? ?str_split(str_split.COUNT) := ty_row_str_split(strValue => str);

? ??

? ? ? IF i >= len THEN

? ? ? ? EXIT;

? ? ? END IF;

? ? ELSE

? ? ? str := SUBSTR(p_str, i, j - i);

? ? ? ?i ? ?:= j + len1;

? ? ? ?str_split.EXTEND;

? ? ? ?str_split(str_split.COUNT) := ty_row_str_split(strValue => str);

? ? END IF;

? END LOOP;

?

?

? RETURN str_split;

END fn_split;

?

?

使用样例:

select to_number(strvalue) as Value from table(fn_split('1,2,3',','))

select to_char(strvalue) as Value from table(fn_split('aa,bb,cc',','))?

热点排行