以前遇到了一次这样的需求,当时没有记录,这一次又遇上了,简单的记录一下。正则表达式
本文我的拙见,如有出入,请指出——来自菜的颤抖
sql
表A中存放了集装箱的信息,一个集装箱一条记录,表B中存放了对于集装箱操做的指令,一条指令包括多个集装箱箱号,经过分号;
切割(TCIU2347687;XUTR3546865
),如今的需求是,对于已经在指令表B中的集装箱,在查询表A时须要过滤掉。函数
not in
, 然而分号分割。not like
,然而[Err] ORA-01427: 单行子查询返回多个行
,表示like
后面只接受模糊查询的单个值。因此必须将分号分割的记录,拆分红单独的记录。
变成:
code
Oracle可以使用regexp_substr函数
实现,实现上面切割的sql为:regexp
select regexp_substr('TCIU2347687;XUTR3546865', '[^;]+', 1, level) JZXXH from dual connect by level <= regexp_count('TCIU2347687;XUTR3546865', ';') + 1
其中regexp_substr
各个参数的含义:blog
TCIU2347687;XUTR3546865
表示须要分割匹配的串(我这里只是作了示例,真实状况下是表的字段)。[^;]+
典型的正则表达式,我这里分号切割,所以肯定分割规则是多个不是分号的字符
,所以遇到分号便结束,完成一个串的获取。1
开始位置,最左端(Oracle下标都是1开始)level
表示第几个匹配上的。select REGEXP_SUBSTR('aaa;bbb','[^;]+',1,1) AS STR FROM dual;
结果就是aaa
, 若是把第二个1变成2,输出就是bbb
。
好了,这部分意图很明显了,下面就是把它每个切割串取出来,看到上面取level个
,而这个level
是个什么东西呢,在这个以前,先看regexp_count(string, c)
函数,这个函数其实很好理解,返回string中c的个数。
而后就是这个level,这是一个伪列,和RowNum类似,string
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <=2;
因此再回到最初的sql,也就很好理解了。select
此致,敬礼im