最近在做公司的狐小E項目(https://www.hixiaoe.com/),要轉Mysql數據庫,但是Mysql 數據庫自己是沒有split函數,就在stackoverflow上搜了一個實現,這里也繼續分享出去,取之於網絡,用之於網格,大家一起學習,進步。
以下就函數的具體實現。
DROP FUNCTION IF EXISTS fn_split; DELIMITER $$ CREATE FUNCTION fn_split ( s TEXT , del CHAR(1) , i INT) RETURNS VARCHAR(1024) DETERMINISTIC -- always returns same results for same input parameters SQL SECURITY INVOKER BEGIN DECLARE n INT ; -- get max number of items SET n = LENGTH(s) - LENGTH(REPLACE(s, del, '')) + 1; IF i > n THEN RETURN NULL ; ELSE RETURN SUBSTRING_INDEX(SUBSTRING_INDEX(s, del, i) , del , -1 ) ; END IF; END$$ DELIMITER ;
建好了函數,我們看一下效果。
下面是使用的結果。
再來看一下,我們把i這個參數換成一個不超出范圍的值會怎么樣
到這里,基礎的split就已經實現了。如果沒有復雜需求的,看到這里就可以了。
在實際使用中,咱們可能會有不同的需求,比如要求你把一個字符串,用split處理成一個表返回,這種情況,我們又不知道字符串里的分割符有多少個。我相信很多人會選擇先取出分隔符的數據,再循環來取的方式來處理。雖然這樣能取出結果,但是我感覺還是麻煩了一些。下面是我的方法。
我在庫里建了一張表(t_split)
在這里,需要說明一下,t_split表中name列,也可以建成int型的。
在表里灌了一些數據(根據我項目的情況,我這里灌了1000條),下面截圖只顯示了部分數據。
看到t_split表中的數據,你是不是能理解name列,為什么也可以建成int型的么?
繼續看這個表的使用,有了這張表,我們用split函數就方便了。下面就是使用效果
如果name列是int型的,那么 上面的語句里的id列就可以替換成那么列了。為什么要用name列呢,最后告訴大家。
有了t_split這張表(需要初始化數據),我們就不需要關心要分割的字符串里有多少個分隔符。這樣用起來就方便多了。
但是如果你的串里要超過1000個分隔符,t_split里的數據就要灌多些。
這種使用的方法需要注意幾個點。t_split表主鍵要有自增設置,生成的ID要從1開始連續斷。如果你的MySql要做主從復制,那請在做主從復制前,把這個表里的數據先生成好,否則做好主從復制后,主鍵ID是主機上,和備機上都是跳號生成,這樣再用t_split配合split函數取據就會漏數據了,大家一定要注意。
如果你建t_split表的時候,把name列建成了int型的,灌數據的時候 name列里的值也是從1到N連續不段的,那么就不用擔心Mysql主從復制的時候自增ID不連續的問題
很高興能夠參加狐小E項目(https://www.hixiaoe.com/)的開發,期望在這個項目里能更快的成長起來,學習到更多Mysql的知識,也希望各位多多指點。
如果大家有更好的方法,歡迎一起討論,一起成長吧~