十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
(1)定义split_type类型:
创新互联专注于栖霞企业网站建设,成都响应式网站建设,商城网站建设。栖霞网站建设公司,为栖霞等地区提供建站服务。全流程按需定制开发,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务
CREATE OR REPLACE TYPE split_type IS TABLE OF VARCHAR2 (4000) /
(2)定义split函数:
CREATE OR REPLACE FUNCTION split (p_str IN VARCHAR2, p_delimiter IN VARCHAR2) RETURN split_type IS j INT := 0; i INT := 1; len INT := 0; len1 INT := 0; str VARCHAR2 (4000); my_split split_type := split_type (); 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); my_split.EXTEND; my_split (my_split.COUNT) := str; IF i = len THEN EXIT; END IF; ELSE str := SUBSTR (p_str, i, j - i); i := j + len1; my_split.EXTEND; my_split (my_split.COUNT) := str; END IF; END LOOP; RETURN my_split; END split; /
(3)存储过程中,使用类似
For T In ( select a,b,c,d from table (split('1,2,3,4',',')) ) Loop
--注意下面的inserti语句,varchar类型的值需要补充引号上去
Execute Immediate ' insert into tableName set fieldName = '||T.a ;
Execute Immediate 'commit';
End Loop;
的查询语句,把分开的结果拼成sql语句并写入到表中。
第一种:oracle字符串分割和提取
分割
create or replace function Get_StrArrayLength
(
av_str varchar2, --要分割的字符串
av_split varchar2 --分隔符号
)
return number
is
lv_str varchar2(1000);
lv_length number;
begin
lv_str:=ltrim(rtrim(av_str));
lv_length:=0;
while instr(lv_str,av_split)0 loop
lv_length:=lv_length+1;
lv_str:=substr(lv_str,instr(lv_str,av_split)+length(av_split),length(lv_str));
end loop;
lv_length:=lv_length+1;
return lv_length;
end Get_StrArrayLength;
提取
create or replace function Get_StrArrayStrOfIndex
(
av_str varchar2, --要分割的字符串
av_split varchar2, --分隔符号
av_index number --取第几个元素
)
return varchar2
is
lv_str varchar2(1024);
lv_strOfIndex varchar2(1024);
lv_length number;
begin
lv_str:=ltrim(rtrim(av_str));
lv_str:=concat(lv_str,av_split);
lv_length:=av_index;
if lv_length=0 then
lv_strOfIndex:=substr(lv_str,1,instr(lv_str,av_split)-length(av_split));
else
lv_length:=av_index+1;
lv_strOfIndex:=substr(lv_str,instr(lv_str,av_split,1,av_index)+length(av_split),instr(lv_str,av_split,1,lv_length)-instr(lv_str,av_split,1,av_index)-length(av_split));
end if;
return lv_strOfIndex;
end Get_StrArrayStrOfIndex;
本文个人拙见,若有出入,请指出——来自菜的颤抖
该方式的效率不高,如何优化,请看 记Oracle中regexp_substr函数的一次调优(速度提高99.5%)
表A中存放了集装箱的信息,一个集装箱一条记录,表B中存放了对于集装箱操作的指令,一条指令包括多个集装箱箱号,通过分号 ; 切割( TCIU2347687;XUTR3546865 ),现在的需求是,对于已经在指令表B中的集装箱,在查询表A时需要过滤掉。
所以必须将分号分割的记录,拆分成单独的记录。
变成:
Oracle可使用 regexp_substr函数 实现,实现上面切割的sql为:
其中 regexp_substr 各个参数的含义:
结果就是 aaa , 如果把第二个1变成2,输出就是 bbb 。
好了,这部分意图很明显了,下面就是把它每一个切割串取出来,看到上面取 level个 ,而这个 level 是个什么东西呢,在这个之前,先看 regexp_count(string, c) 函数,这个函数其实很好理解,返回string中c的个数。
然后就是这个level,这是一个伪列,和RowNum相似,
所以再回到最初的sql,也就很好理解了。
有时候查询的时候会进行拆分,对某串字符串进行拆分的时候可以用:
select regexp_substr('aaaaa,bbbb,cc,ddddd,ee','[^,]+',1,level)
from dual
connect by level = regexp_count('aaaaa,bbbb,cc,ddddd,ee',',')+1;
对于表中的每一行进行拆分,则需自身与自身递归,但是connect by deptno = prior deptno 会报错误,因此需要使用prior dbms_random.value is not null 来欺骗oracle
例: select t.*,regexp_substr(t.ename,'[^,]+',1,level)
from emp_bak t
connect by level = regexp_count(t.ename,',')+1
and t.ename = prior t.ename
and prior dbms_random.value is not null;
其实不需要拆分表,分区就可以,还是原来的表名,只是将原来的表分成了若干的分区,这样能起到分表的效果,还不用分成很多的表。
比如你原来的表的名字是A,那么将该表改为A1,然后从新建立一个分区表A,分区的依据是班级,也就是list分区,也就是一般意义上的列表分区表。
然后再将A1的数据插入新A表就可以了。
至于分区表的建立方式,往上很多,可以自行查找。
这样操作查询的语句不需要变,只是在不跨分区查询的情况下,相当于分成了若干张表去查询。比如查询1班的成绩,那么就是在1班的分区内,不会有2班的问题,就相当于你用一个指头就能解决问题,不会动用这个手一样。
如果分表的话,那么假设有12个班,那么就要建立12张表,这样的话,语句就要写12次,冗余太大了。
分割字符串用substr函数即可。
如:字符串为abc123,现在要截取成abc和123。
select substr('abc123',1,3),substr('abc123',4,3) from dual;
函数说明:
substr('abc123',1,3)
其中abc123是要被截取的字符串,1,代表从第一位开始截取,3代表要截取的长度。