1 概述
- 能够完成该功能的代码有很多,以下为我认为 '最简写、优雅' 的写法
- 核心思想:regexp_substr('abc1,cbd2,db3,db5', '[^,]+', 1, rownum)
2 核心代码
--****************************************************************
-- regexp_substr(string, pattern, position, occurrence, modifier)
-- string : 要处理的字符串
-- pattern :正则表达式,[^,]+ : 至少有一个 ','
-- position : 起始位置,默认 1
-- occurrence: 获取第几个分隔出来的组(字符串分隔后排列成组)
-- modifier : 模式('i': 不区分大小写,'c': 区分大小写, 默认 'c')
--****************************************************************
select rownum 次数,
regexp_substr('abc1,cbd2,db3,db5', '[^,]+', 1, rownum) 字符串
from dual
connect by rownum <= length('abc1,cbd2,db3,db5') -
length(replace('abc1,cbd2,db3,db5', ',', '')) + 1;
3 完整代码
3.1 测试代码
- 建议,在 测试窗口(T) 操作
字符串转成数组:
DECLARE
-- Non-scalar parameters require additional processing
i_str VARCHAR2(100) := 'a,b,c';
i_separator VARCHAR2(1) := ',';
o_string_array pkg_public_utility.string_array;
o_flag VARCHAR2(1);
o_message VARCHAR2(100);
BEGIN
-- Call the procedure
pkg_public_utility.convert_string_to_array(i_str => i_str,
i_separator => i_separator,
o_string_array => o_string_array,
o_flag => o_flag,
o_message => o_message);
-- 测试语句
IF o_string_array.first IS NULL THEN
dbms_output.put_line(o_flag);
dbms_output.put_line(o_message);
RETURN;
END IF;
FOR i IN o_string_array.first .. o_string_array.last LOOP
NULL;
END LOOP;
END;
测试结果:
0 : a
1 : b
2 : c
数组转成字符串:
DECLARE
-- Non-scalar parameters require additional processing
i_string_array pkg_public_utility.string_array;
i_separator VARCHAR2(1) := ',';
o_string VARCHAR2(100);
o_flag VARCHAR2(1);
o_message VARCHAR2(100);
BEGIN
i_string_array(i_string_array.count) := 'a';
i_string_array(i_string_array.count) := 'b';
i_string_array(i_string_array.count) := 'c';
-- Call the procedure
pkg_public_utility.convert_array_to_string(i_string_array => i_string_array,
i_separator => i_separator,
o_string => o_string,
o_flag => o_flag,
o_message => o_message);
-- 测试语句
dbms_output.put_line(o_string);
END;
测试结果:
a,b,c
3.2 源代码
Package:
CREATE OR REPLACE PACKAGE pkg_public_utility IS
TYPE string_array IS TABLE OF VARCHAR2(4000) INDEX BY PLS_INTEGER;
--*******************************************************
--功能说明:"字符串" 转为 "数组"
--参数说明:i_str 字符串
-- i_separator 分隔符
-- o_string_array 字符串数组
-- o_flag 执行成功标识,Y:成功,N:失败
-- o_message 执行返回信息
--创建人 :YoYo
--创建时间:2020-12-15
--更改记录:
--*******************************************************
PROCEDURE convert_string_to_array(i_str IN VARCHAR2,
i_separator IN VARCHAR2,
o_string_array OUT string_array,
o_flag OUT VARCHAR2,
o_message OUT VARCHAR2);
--*******************************************************
--功能说明:"数组" 转为 "字符串"
--参数说明:i_string_array 字符串数组
-- i_separator 分隔符
-- o_string_array 字符串
-- o_flag 执行成功标识,Y:成功,N:失败
-- o_message 执行返回信息
--创建人 :YoYo
--创建时间:2020-12-15
--更改记录:
--*******************************************************
PROCEDURE convert_array_to_string(i_string_array IN string_array,
i_separator IN VARCHAR2,
o_string OUT VARCHAR2,
o_flag OUT VARCHAR2,
o_message OUT VARCHAR2);
END pkg_public_utility;
Package Body:
CREATE OR REPLACE PACKAGE BODY pkg_public_utility IS
--*******************************************************
--功能说明:"字符串" 转为 "数组"
--参数说明:i_str 字符串
-- i_separator 分隔符
-- o_string_array 字符串数组
-- o_flag 执行成功标识,Y:成功,N:失败
-- o_message 执行返回信息
--创建人 :YoYo
--创建时间:2020-12-15
--更改记录:
--*******************************************************
PROCEDURE convert_string_to_array(i_str IN VARCHAR2,
i_separator IN VARCHAR2,
o_string_array OUT string_array,
o_flag OUT VARCHAR2,
o_message OUT VARCHAR2) IS
BEGIN
--1.入参校验
IF TRIM(i_str) IS NULL THEN
o_flag := 'N';
o_message := '入参为空!字符串 i_str 为空';
RETURN;
ELSIF TRIM(i_separator) IS NULL THEN
o_flag := 'N';
o_message := '入参为空!分隔符 i_separator 为空';
RETURN;
ELSIF TRIM(both i_separator FROM i_str) <> i_str THEN
o_flag := 'N';
o_message := '入参格式不对!分隔符不能在字符串两侧:字符串 i_str = "' || i_str ||
'" 分隔符 i_separator = "' || i_separator || '"';
RETURN;
END IF;
-- 2.将字符串拆分为数组
IF instr(i_str, i_separator) = 0 THEN
o_flag := 'Y';
o_message := '仅有一个子串';
o_string_array(o_string_array.count) := i_str;
RETURN;
END IF;
FOR i IN 1 .. regexp_count(i_str || i_separator, i_separator) LOOP
o_string_array(o_string_array.count) := regexp_substr(i_str,
'[^' ||
i_separator || ']+',
1,
i);
END LOOP;
o_flag := 'Y';
o_message := '执行成功!';
END convert_string_to_array;
--*******************************************************
--功能说明:"数组" 转为 "字符串"
--参数说明:i_string_array 字符串数组
-- i_separator 分隔符
-- o_string_array 字符串
-- o_flag 执行成功标识,Y:成功,N:失败
-- o_message 执行返回信息
--创建人 :YoYo
--创建时间:2020-12-15
--更改记录:
--*******************************************************
PROCEDURE convert_array_to_string(i_string_array IN string_array,
i_separator IN VARCHAR2,
o_string OUT VARCHAR2,
o_flag OUT VARCHAR2,
o_message OUT VARCHAR2) IS
BEGIN
-- 1.入参校验
IF i_string_array.count = 0 THEN
o_flag := 'N';
o_message := '数组为空!';
RETURN;
END IF;
IF i_separator IS NULL THEN
o_flag := 'N';
o_message := '分隔符 i_separator 不能为空!';
END IF;
--2.将数组拆分为字符串
FOR i IN i_string_array.first .. i_string_array.last LOOP
o_string := o_string || i_string_array(i) || i_separator;
END LOOP;
o_string := rtrim(o_string, i_separator);
o_flag := 'Y';
o_message := '执行成功!';
END convert_array_to_string;
END pkg_public_utility;