以前遇到了一次這樣的需求,當時沒有記錄,這一次又遇上了,簡單的記錄一下。正則表達式
本文我的拙見,如有出入,請指出——來自菜的顫抖
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