美文网首页
一些关于存储过程的知识点

一些关于存储过程的知识点

作者: 呼噜噜睡 | 来源:发表于2024-07-14 08:04 被阅读0次

    啊,什么,你在写存储过程?阿里巴巴开发手册不是已经明确说了禁用存储过程了吗?存储过程难以调式、不支持对象数组这些东西,简单逻辑需要用奇技淫巧绕一大圈才能实现、编写了几百行的存储过程,谁看谁闹心、难以适应大量数据...当然最主要的,我是个渣渣,不想写这东西了?

    好的,看来这位同学对存储过程有偏见嘛?你看到戴金丝眼镜的人士,就要上去打爆人家的眼镜吗?哈哈,首先呢,咱们呀,不是阿里巴巴,所以不用搞什么规范,不要给我扯,你就说,这个东西你能不能实现!调试困难,也许吧,多加几个查询中间变量的东西,可以半猜测半悬疑的搞定。确实不支持对象和数组,这玩意要搞成js那样,那不得上天,这是另一种编程艺术的范畴了。对于前任遗留的东西,我从来不关心,我都绕着走,要么不服气自己再来实现一遍,要么就服个软,能用就用,能省就省,得过且过,谁跟时间过不去呢?还有,你说难以适应大量数据,我就问你,你什么时候看见了大量的数据?莫不是看到了大波浪,浮想联翩吧,那几个亿买卖你怕是做不成啰。当然,我是渣渣,这一点我完全不反驳,每个老司机都是从青葱岁月过来的,写着写着就熟悉了。最后呀,不得不说,存储过程有时候真的很快,车速快、稳定性好,大车灯,配置好,就是很费油...

    咳咳,打住,这位同学,虽然我不知道你在说些什么,但我听着很奇怪的样子。接下来,言归正传,今天讲一讲mysql里面存储过程编写的一些小细节、小坑、注意点之类的吧。

    1、输入、输出参数、中间变量,这个变量名称不要跟mysql关键字、要查询或者更改的表明、字段名相同。如果有相同,它可能会出现既不报错、又不出结果的情况。

    CREATE DEFINER=`root`@`%` PROCEDURE `p_xxx`(IN sys_code varchar(50))
    BEGIN
        -- 省略逻辑
        -- 定义游标,并将sql结果集赋值到游标中  
        DECLARE cur_xxx CURSOR FOR SELECT sys_code FROM t_sys_config WHERE sys_code = sys_code;
    

    上面这样使用,就可能出问题,避免这样写。一般我喜欢给所有自定义变量、参数加上下划线后缀,这样一眼就能看出哪些是我自己定义的变量。

    2、变量要先定义后使用、游标先定义后使用、各种HANDLER定义在游标之后。

    3、如何判断游标结束?使用HANDLER

      -- cur_XXX是否结束的变量
      DECLARE finish int DEFAULT 0;
      -- 定义游标,并将sql结果集赋值到游标中
      DECLARE cur_xxx CURSOR FOR SELECT xxx_SQL;
      -- 声明当游标遍历完后将标志变量置成某个值
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET finish = 1;
    

    在while循环中,判断finish变量是否等于1,如果等于了,则游标遍历完毕了。

    4、存储过程没有try catch语句,如果在一个循环中有很多次sql执行,只要一次不成功,我就要回滚修改,该如何实现?

      -- 定义sql语句执行是否正确的变量
      DECLARE sql_error_ INTEGER DEFAULT 0;
      -- sql语句执行错误 设置值
      DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET sql_error_ = 1;
    

    在循环中,如果有sql执行错误,则sql_seeor_=1,在循环中一旦判定该值等于1,结束循环。结束后,sql执行有错误,那么回滚就可以了。

    5、游标查询字段和赋值字段,名称要不一致,如果一样,就会出问题,比如你查询sys_code字段值,赋值给sys_code变量,那就会出问题。

      -- 定义游标,并将sql结果集赋值到游标中
      DECLARE cur_xxx CURSOR FOR SELECT sys_code,sys_name FROM t_sys_config;
      -- 打开游标
      OPEN cur_need_convert;
      -- 将游标中的值赋值给变量,注意:变量名不要和返回的列名同名,变量顺序要和sql结果列的顺序一致
      FETCH cur_xxx INTO sys_code_,sys_name_;
    

    6、CONCAT函数,如果里面参数有null值的,则最后结果为null,因此一定要注意对null值的处理,要不然,可能得不到你想要的执行效果。

    7、如何判断以逗号分隔的字符串,分隔后几个对象,如 123,456,789 ,逗号分隔开以后,有3个对象。

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

    原理就是计算整个字符串的长度,以及将这个字符串中的逗号去除以后的长度,两个长度相减即可得到。

    8、上面计算出了对象个数,现在要求把这些对象一个一个的分割开来,做其余逻辑操作 如果 123,456,789 分割开来得到 123 456 789 。这个要用到循环,去处理。

    SET deal_count_ = 0;
    WHILE deal_count_ < count_ DO
        -- 截取出单个
        SET single_s = SUBSTRING_INDEX(xxx,',',1);
        -- 将已经截取出来的从原字符串中给剔除掉
        SET xxx = REPLACE(xxx,CONCAT(IFNULL(xxx,''),','),'');
        -- 已经处理数+1
        SET deal_count_ = count_ + 1;
        -- 其余逻辑
    END WHILE;
    

    好了,今天就说这么多,你们学会了多少呢?

    相关文章

      网友评论

          本文标题:一些关于存储过程的知识点

          本文链接:https://www.haomeiwen.com/subject/fwzqhjtx.html