工作中用到的oracle字符串分割整理
oracle部分:
定义类型(用于字符串分割):
create or replace
TYPE "STR_SPLIT"
IS TABLE OF VARCHAR2 (4000);
字符串分割函数:
create or replace
FUNCTION splitstr(p_string IN VARCHAR2, p_delimiter IN
VARCHAR2)
RETURN str_split
PIPELINED
AS
v_length NUMBER
:= LENGTH(p_string);
v_start NUMBER := 1;
v_index
NUMBER;
BEGIN
WHILE(v_start <= v_length)
LOOP
v_index := INSTR(p_string, p_delimiter, v_start);
IF v_index = 0
THEN
PIPE
ROW(SUBSTR(p_string, v_start));
v_start := v_length + 1;
ELSE
PIPE ROW(SUBSTR(p_string, v_start, v_index -
v_start));
v_start := v_index + 1;
END IF;
END
LOOP;
RETURN;
END splitstr;
运行效果:
sql:select CRM.SPLITSTR(‘,100001240,,100001241,4567890,‘,‘,‘) from dual;
sql:SELECT * FROM TABLE(SPLITSTR(‘,100001240,,100001241,4567890,‘,‘,‘))
引申sql:
SELECT * FROM TABLE(SPLITSTR(‘,100001240,,100001241,4567890,‘,‘,‘)) WHERE column_value IN (‘100001240‘,‘100001241‘,‘2345‘,‘234567‘);
mybaits+oracle:
sql:(说明:将字符串以特定字符分割,然后拼接成特定记录,然后和已存在表数据做比较(按特定字段)筛选出不存在的记录然后再做记录拼接完成插入操作)
功能说明:可以达到批量插入不用管记录是否存在,已存在的记录会被排除在外
insert into CRM.d_business_link (
select t.*,
#{account,jdbcType=VARCHAR} ,sysdate from
(SELECT
#{customer,jdbcType=VARCHAR} AS HOST,
customers.*,
#{relationship,jdbcType=VARCHAR} AS RELATION
FROM
(SELECT * FROM
TABLE(CRM.SPLITSTR(#{selected_dCuscode,jdbcType=VARCHAR},‘,‘))
) customers
minus
select
Host,CUSTOMER,relation from CRM.d_business_link
)t)
下面这个不知道该说设计有问题还是需求变态但也不小心给实现了,真佩服我自己啊,
首先说设计:字典表(应该懂的吧用于动态维护:按分组的形式保存着字典间的映射关系)
一个表(产品表)用到字典表 这样设计没啥问题吧,问题就在于一个字段采用分隔符的形式保存了字典项。
需求:把一批记录通过字典表转换成能识别的有意义记录。
原始记录:
gjzdgc,tljs,slsl,shsc,jcjs,qljs
gycf,slsl,sydc,ggjz,jcjs,qljs
slsl,shsc,sydc,qljs
gjzdgc,gsgl,yzsc,shsc,jcjs,qljs
grzx,gsgl,qljs
grzx
gjzdgc,gsgl,slsl,shsc,sydc,qljs
目标记录:
国家重点工程,水利枢纽,商混生产,铁路工程,机场工程,桥梁工程
水利枢纽,商业地产,公共建筑,工业厂房,机场工程,桥梁工程
水利枢纽,商混生产,商业地产,桥梁工程
国家重点工程,高速公路,商混生产,预制生产,机场工程,桥梁工程
个人装修,高速公路,桥梁工程
个人装修
国家重点工程,高速公路,水利枢纽,商混生产,商业地产,桥梁工程
sql:
select
(
SELECT WMSYS.WM_CONCAT(dd_infoname)
FROM
C_DICTIONARY_DETAILS cdd
WHERE cdd.DD_INFOCODE IN (select * from
table(splitstr(p_userful,‘,‘)))
) as P_USERFUL,p_userful
,a.*
FROM
c_product a;
思路:
1.
SELECT dd_infoname
FROM C_DICTIONARY_DETAILS cdd
WHERE cdd.DD_INFOCODE
IN (select * from table(splitstr(‘gycf,slsl,sydc,ggjz,jcjs,qljs‘,‘,‘)))
2.通过函数WM_CONCAT将记录转换成以逗号分割的一条记录(可好像是10g后才有的,挺强大的需详细了解请问度娘)
SELECT WM_CONCAT(dd_infoname)
FROM C_DICTIONARY_DETAILS cdd
WHERE
cdd.DD_INFOCODE IN (select * from
table(splitstr(‘gycf,slsl,sydc,ggjz,jcjs,qljs‘,‘,‘)))
3.oracle 底层处理了不太清楚
sql:
select
(
SELECT WM_CONCAT(dd_infoname)
FROM C_DICTIONARY_DETAILS
cdd
WHERE cdd.DD_INFOCODE IN (select * from
table(splitstr(p_userful,‘,‘)))
) as P_USERFUL,p_userful
FROM c_product
;
至此ok。完成了
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。