一些關(guān)于存儲(chǔ)過程的知識(shí)點(diǎn)

啊,什么,你在寫存儲(chǔ)過程?阿里巴巴開發(fā)手冊(cè)不是已經(jīng)明確說了禁用存儲(chǔ)過程了嗎?存儲(chǔ)過程難以調(diào)式、不支持對(duì)象數(shù)組這些東西,簡單邏輯需要用奇技淫巧繞一大圈才能實(shí)現(xiàn)、編寫了幾百行的存儲(chǔ)過程,誰看誰鬧心、難以適應(yīng)大量數(shù)據(jù)...當(dāng)然最主要的,我是個(gè)渣渣,不想寫這東西了?

好的,看來這位同學(xué)對(duì)存儲(chǔ)過程有偏見嘛?你看到戴金絲眼鏡的人士,就要上去打爆人家的眼鏡嗎?哈哈,首先呢,咱們呀,不是阿里巴巴,所以不用搞什么規(guī)范,不要給我扯,你就說,這個(gè)東西你能不能實(shí)現(xiàn)!調(diào)試?yán)щy,也許吧,多加幾個(gè)查詢中間變量的東西,可以半猜測(cè)半懸疑的搞定。確實(shí)不支持對(duì)象和數(shù)組,這玩意要搞成js那樣,那不得上天,這是另一種編程藝術(shù)的范疇了。對(duì)于前任遺留的東西,我從來不關(guān)心,我都繞著走,要么不服氣自己再來實(shí)現(xiàn)一遍,要么就服個(gè)軟,能用就用,能省就省,得過且過,誰跟時(shí)間過不去呢?還有,你說難以適應(yīng)大量數(shù)據(jù),我就問你,你什么時(shí)候看見了大量的數(shù)據(jù)?莫不是看到了大波浪,浮想聯(lián)翩吧,那幾個(gè)億買賣你怕是做不成啰。當(dāng)然,我是渣渣,這一點(diǎn)我完全不反駁,每個(gè)老司機(jī)都是從青蔥歲月過來的,寫著寫著就熟悉了。最后呀,不得不說,存儲(chǔ)過程有時(shí)候真的很快,車速快、穩(wěn)定性好,大車燈,配置好,就是很費(fèi)油...

咳咳,打住,這位同學(xué),雖然我不知道你在說些什么,但我聽著很奇怪的樣子。接下來,言歸正傳,今天講一講mysql里面存儲(chǔ)過程編寫的一些小細(xì)節(jié)、小坑、注意點(diǎn)之類的吧。

1、輸入、輸出參數(shù)、中間變量,這個(gè)變量名稱不要跟mysql關(guān)鍵字、要查詢或者更改的表明、字段名相同。如果有相同,它可能會(huì)出現(xiàn)既不報(bào)錯(cuò)、又不出結(jié)果的情況。

CREATE DEFINER=`root`@`%` PROCEDURE `p_xxx`(IN sys_code varchar(50))
BEGIN
    -- 省略邏輯
    -- 定義游標(biāo),并將sql結(jié)果集賦值到游標(biāo)中  
    DECLARE cur_xxx CURSOR FOR SELECT sys_code FROM t_sys_config WHERE sys_code = sys_code;

上面這樣使用,就可能出問題,避免這樣寫。一般我喜歡給所有自定義變量、參數(shù)加上下劃線后綴,這樣一眼就能看出哪些是我自己定義的變量。

2、變量要先定義后使用、游標(biāo)先定義后使用、各種HANDLER定義在游標(biāo)之后。

3、如何判斷游標(biāo)結(jié)束?使用HANDLER

  -- cur_XXX是否結(jié)束的變量
  DECLARE finish int DEFAULT 0;
  -- 定義游標(biāo),并將sql結(jié)果集賦值到游標(biāo)中
  DECLARE cur_xxx CURSOR FOR SELECT xxx_SQL;
  -- 聲明當(dāng)游標(biāo)遍歷完后將標(biāo)志變量置成某個(gè)值
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET finish = 1;

在while循環(huán)中,判斷finish變量是否等于1,如果等于了,則游標(biāo)遍歷完畢了。

4、存儲(chǔ)過程沒有try catch語句,如果在一個(gè)循環(huán)中有很多次sql執(zhí)行,只要一次不成功,我就要回滾修改,該如何實(shí)現(xiàn)?

  -- 定義sql語句執(zhí)行是否正確的變量
  DECLARE sql_error_ INTEGER DEFAULT 0;
  -- sql語句執(zhí)行錯(cuò)誤 設(shè)置值
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET sql_error_ = 1;

在循環(huán)中,如果有sql執(zhí)行錯(cuò)誤,則sql_seeor_=1,在循環(huán)中一旦判定該值等于1,結(jié)束循環(huán)。結(jié)束后,sql執(zhí)行有錯(cuò)誤,那么回滾就可以了。

5、游標(biāo)查詢字段和賦值字段,名稱要不一致,如果一樣,就會(huì)出問題,比如你查詢sys_code字段值,賦值給sys_code變量,那就會(huì)出問題。

  -- 定義游標(biāo),并將sql結(jié)果集賦值到游標(biāo)中
  DECLARE cur_xxx CURSOR FOR SELECT sys_code,sys_name FROM t_sys_config;
  -- 打開游標(biāo)
  OPEN cur_need_convert;
  -- 將游標(biāo)中的值賦值給變量,注意:變量名不要和返回的列名同名,變量順序要和sql結(jié)果列的順序一致
  FETCH cur_xxx INTO sys_code_,sys_name_;

6、CONCAT函數(shù),如果里面參數(shù)有null值的,則最后結(jié)果為null,因此一定要注意對(duì)null值的處理,要不然,可能得不到你想要的執(zhí)行效果。

7、如何判斷以逗號(hào)分隔的字符串,分隔后幾個(gè)對(duì)象,如 123,456,789 ,逗號(hào)分隔開以后,有3個(gè)對(duì)象。

(case when length(xxx) = 0 THEN 0 ELSE (length(xxx) - LENGTH(REPLACE(xxx,',','')) + 1) END) AS count_

原理就是計(jì)算整個(gè)字符串的長度,以及將這個(gè)字符串中的逗號(hào)去除以后的長度,兩個(gè)長度相減即可得到。

8、上面計(jì)算出了對(duì)象個(gè)數(shù),現(xiàn)在要求把這些對(duì)象一個(gè)一個(gè)的分割開來,做其余邏輯操作 如果 123,456,789 分割開來得到 123 456 789 。這個(gè)要用到循環(huán),去處理。

SET deal_count_ = 0;
WHILE deal_count_ < count_ DO
    -- 截取出單個(gè)
    SET single_s = SUBSTRING_INDEX(xxx,',',1);
    -- 將已經(jīng)截取出來的從原字符串中給剔除掉
    SET xxx = REPLACE(xxx,CONCAT(IFNULL(xxx,''),','),'');
    -- 已經(jīng)處理數(shù)+1
    SET deal_count_ = count_ + 1;
    -- 其余邏輯
END WHILE;

好了,今天就說這么多,你們學(xué)會(huì)了多少呢?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容