名站网址导航为大家提供关于数据库教程相关的教程网站知识。
最近项目中有很多需要做批量操作办法的需求,客户端把一组逗号分隔的ID字符串传给网站数据库,存储过程就需要把它们分割,然后逐个处理。Oracle Max函数使用中出现的问题
复制具体相关代码 具体相关代码如下:,SELECT MAX(RE_DATE) INTO V_RE_DATE FROM T_RECORDING WhERE ID ='100010010102',复制具体相关代码 具体相关代码如下:,EXCEPTION WhEN NO_DATA_FOUND ThEN NULL; WhEN OThERS ThEN ERR_CODE :=-2000; ERR_MSG :=SQLERRM; RETURN
以往的处理相关方式有如下几种:
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;
/