oracle 实现 split 函数 (返回数组)
2015-12-14 17:49
651 查看
首先,这是最近在公司执行一个任务的时候遇到的情况,分享一下,代码来源于互联网,非原创。
如果你的存储过程的参数个数不定,比如你要处理A条件、B条件2种情况,或者A条件、C条件、F条件的情况,
每次的条件的个数和条件都是变动的,这样你的存储过程参数就不好做。这种情况下,你可以只输入一个参数,
多个条件用特殊字符如逗号分隔,然后对这个条件截断拆分之后循环处理,类似于jquery的split方法。然而,oracle
并没有这样的函数,你需要自己编写,以下是收录的一个有用的将oracle字符串截断成数组(oracle复合数据类型)的function。
CREATE OR REPLACE PACKAGE BODY StatisPackage AS
/*****************************************************************************************************
Description:实现 split 函数 (返回数组)
Param:uni_array:=f_split_string('aa,bb,cc,dd',',')
Creator: DATE:2015-12-13
*****************************************************************************************************/
FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2)
RETURN ty_str_split
IS
j INT := 0;
i INT := 1;
len INT := 0;
len1 INT := 0;
str VARCHAR2 (4000);
str_split ty_str_split := ty_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) := 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) := str;
END IF;
END LOOP;
RETURN str_split;
END fn_split;
end StatisPackage;
测试:
DECLARE
CURSOR c
IS
SELECT *
FROM TABLE (CAST (fn_split ('1;;12;;123;;1234;;12345', ';;') AS ty_str_split
)
);
r c%ROWTYPE;
BEGIN
OPEN c;
LOOP
FETCH c INTO r;
EXIT WHEN c%NOTFOUND;
DBMS_OUTPUT.put_line (r.column_value);
END LOOP;
CLOSE c;
END;
/
结果:
1
12
123
1234
12345
方法二;
create or replace function f_split_string (var_str varchar2,var_split varchar2)
return t_ret_table
is
var_out t_ret_table; --定义变量
var_tmp varchar2(100);
var_element varchar2(100);
begin
var_tmp := var_str;
var_out := t_ret_table();
--如果存在匹配的分割符
while instr(var_tmp,var_split)>0 loop
var_element:=substr(var_tmp,1,instr(var_tmp,var_split)-1);
var_tmp := substr(var_tmp,instr(var_tmp,var_split)+length(var_split),length(var_tmp));
var_out.extend(1);
var_out(var_out.count) := var_element;
end loop;
var_out.extend(1);
var_out(var_out.count) := var_tmp;
return var_out;
end f_split_string;
在代码里,uni_array是一个table of varchar2的数组,就可以uni_array:=f_split_string('aa,bb,cc,dd',',')
将aa、bb、cc、dd四个元素装入uni_array,然后循环处理。
如果你的存储过程的参数个数不定,比如你要处理A条件、B条件2种情况,或者A条件、C条件、F条件的情况,
每次的条件的个数和条件都是变动的,这样你的存储过程参数就不好做。这种情况下,你可以只输入一个参数,
多个条件用特殊字符如逗号分隔,然后对这个条件截断拆分之后循环处理,类似于jquery的split方法。然而,oracle
并没有这样的函数,你需要自己编写,以下是收录的一个有用的将oracle字符串截断成数组(oracle复合数据类型)的function。
CREATE OR REPLACE PACKAGE StatisPackage AS TYPE StatisList IS REF CURSOR; TYPE ty_str_split IS TABLE OF VARCHAR2 (4000); PROCEDURE Statis_Planning(PlanningId IN nvarchar2,SolutionID IN nvarchar2,indextypeid in NUMBER,cversionid IN nvarchar2,Indicators in nvarchar2,p_cur out StatisList); FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2) return ty_str_split; END StatisPackage;
CREATE OR REPLACE PACKAGE BODY StatisPackage AS
/*****************************************************************************************************
Description:实现 split 函数 (返回数组)
Param:uni_array:=f_split_string('aa,bb,cc,dd',',')
Creator: DATE:2015-12-13
*****************************************************************************************************/
FUNCTION fn_split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2)
RETURN ty_str_split
IS
j INT := 0;
i INT := 1;
len INT := 0;
len1 INT := 0;
str VARCHAR2 (4000);
str_split ty_str_split := ty_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) := 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) := str;
END IF;
END LOOP;
RETURN str_split;
END fn_split;
end StatisPackage;
测试:
DECLARE
CURSOR c
IS
SELECT *
FROM TABLE (CAST (fn_split ('1;;12;;123;;1234;;12345', ';;') AS ty_str_split
)
);
r c%ROWTYPE;
BEGIN
OPEN c;
LOOP
FETCH c INTO r;
EXIT WHEN c%NOTFOUND;
DBMS_OUTPUT.put_line (r.column_value);
END LOOP;
CLOSE c;
END;
/
结果:
1
12
123
1234
12345
方法二;
create or replace function f_split_string (var_str varchar2,var_split varchar2)
return t_ret_table
is
var_out t_ret_table; --定义变量
var_tmp varchar2(100);
var_element varchar2(100);
begin
var_tmp := var_str;
var_out := t_ret_table();
--如果存在匹配的分割符
while instr(var_tmp,var_split)>0 loop
var_element:=substr(var_tmp,1,instr(var_tmp,var_split)-1);
var_tmp := substr(var_tmp,instr(var_tmp,var_split)+length(var_split),length(var_tmp));
var_out.extend(1);
var_out(var_out.count) := var_element;
end loop;
var_out.extend(1);
var_out(var_out.count) := var_tmp;
return var_out;
end f_split_string;
在代码里,uni_array是一个table of varchar2的数组,就可以uni_array:=f_split_string('aa,bb,cc,dd',',')
将aa、bb、cc、dd四个元素装入uni_array,然后循环处理。
相关文章推荐
- Oracled数据库的进一步理解
- Oracle中的join
- Oracle 表空间迁移
- ORACLE多表关联UPDATE 语句
- Oracle12c新特性之基本操作
- oracle数据库rman备份计划及恢复
- Oracle 收集统计信息11g和12C在差异
- oracle 表锁的问题
- 用单例连接oracle数据库
- oracle批量转库工作,比较快捷的方式
- PROC简单的用例--VC连接ORACLE
- Linux中Oracle环境变量配制
- Oracle创建表空间和用户
- Oracle创建表空间和用户
- Oracle使用记录
- oracle新增(ibatis)
- CentOS7.1安装Oracle 12.1客户端以及cx_Oracle
- 问题:oracle 两个表之间的修改;结果:ORACLE 两个表之间更新的实现
- oracle 对对表匹配的进行修改匹配不上的可以进行新增 (MERGE INTO)
- 关于Oracle有两个或者多个实例时,用SID来区分目前oralce使用的是哪个实例。