• 存储过程常见错误合集


    有如下存储过程:

    DROP PROCEDURE IF EXISTS pro_import_under_take_count;
    CREATE PROCEDURE pro_import_under_take_count ()
    BEGIN
    /* 定义每月的第一天 */
    DECLARE MonthFirstDay varchar(12) ;//定义的变量没哟写@符号,后期在使用的过程中也不要用使用@varible,直接写成最原始定义的变量名,
    DECLARE Month_now varchar(20) ;
    DECLARE under_year varchar(4) ;
    DECLARE under_month varchar(2) ;//declare 定义的变量声明一定要在select赋值语句的上面,不然创建存储过程报错!!!折磨了我大半天,谨记
    DECLARE done INT DEFAULT 0; 
    DECLARE totalRow INT DEFAULT 0; 
    DECLARE orgid VARCHAR(50);
    /* 首先检查每个部门工单表中是否有本月工作考核的数据 使用游标进行遍历*/
    DECLARE result CURSOR FOR SELECT org_id FROM event_undertake  GROUP BY org_id ;
    #HAVING  under_take_time>=@MonthFirstDay AND under_take_time<=@Month_now;//这是错误的,谨记!!!
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
    SELECT DATE_FORMAT(NOW(), '%Y-%m-01') INTO MonthFirstDay; //select赋值语句 变量值:“2017-09-03”格式
    SELECT NOW() INTO Month_now;  //select赋值语句 变量值:“2017-09-03 19:32:23”格式
    SELECT DATE_FORMAT(NOW(), '%Y') INTO under_year; //select赋值语句 变量值:“2017”格式(获取年份)
    SELECT DATE_FORMAT(NOW(), '%m') INTO under_month; //select赋值语句 变量值:“09”格式(获取月份)
    
    OPEN result;
        REPEAT
            FETCH result INTO orgid;
            IF done !=1 THEN
                /* 判断该部门是否存在本月的承办工单统计数据 */
                SELECT COUNT(*) INTO totalRow from event_undertake_count euc 
                    WHERE euc.under_take_year=under_year 
                            AND euc.under_take_month=under_month 
                            AND euc.count_type='1' AND euc.org_id = orgid;
                IF totalRow != 0 THEN
                /*存在,进行更新操作*/
                    SET totalRow = 6;
                    UPDATE event_undertake_count SET     
                        under_take_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid  AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now)
                        ,not_end_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.end_status='0' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now )
                        ,end_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.end_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now )
                        ,on_time_end_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.over_time_status='0' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now )
                        ,over_time_end_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.over_time_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now)
                        ,do_well_count=(SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.do_well_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now)
                    WHERE under_take_year=under_year AND under_take_month=under_month AND count_type='1' AND org_id = orgid;
                
                ELSE
                /*不存在,进行插入操作*/
                    INSERT INTO event_undertake_count (id, org_id, under_take_year, under_take_month, count_type, under_take_count, not_end_count, end_count, on_time_end_count, over_time_end_count, do_well_count, create_time)
                    SELECT 
                        (SELECT REPLACE (UUID(), '-', '')) AS id, 
                        (SELECT orgid) AS org_id,
                        (SELECT under_year) AS under_take_year,
                        (SELECT under_month) AS under_take_month,
                        (SELECT '1') AS count_type,
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS under_take_count ,
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.end_status='0' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS not_end_count ,
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.end_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS end_count , 
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.over_time_status='0' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS on_time_end_count ,
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.over_time_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS over_time_end_count ,
                        (SELECT COUNT(*)  from event_undertake e  WHERE e.org_id=orgid AND e.do_well_status='1' AND e.under_take_time>=MonthFirstDay AND e.under_take_time<=Month_now ) AS do_well_count ,
                        (SELECT Month_now) AS create_time;
    
                END IF;
                /*ceshi */
                #SELECT orgid,totalRow,under_year,under_month;
            END IF;
        UNTIL done END REPEAT;
    CLOSE result;
    #SELECT MonthFirstDay,Month_now,under_year,under_month;
    END
    
    #测试
    CALL pro_import_under_take_count();

    重要点:

    1、游标中 FETCH result INTO orgid; 中orgid不可以跟result中取出来的字段一样,否则取不出来数据,(郁闷了我半天,午睡都没有睡)

    2、存储过程定义declare只能放在最上面,其次是select语句;

    3、SQL语句生产32位UUID:SELECT REPLACE(UUID(),'-','') AS id;

    4、select 查询 涉及 where group by ,having 的时候,查询的顺序

    select COUNT(*)as '>20岁人数',classid  from Table1 where sex='' group by classid,age having age>20 
    • 需要注意说明:当同时含有where子句、group by 子句 、having子句及聚集函数时,执行顺序如下:
    • 执行where子句查找符合条件的数据;
    • 使用group by 子句对数据进行分组;对group by 子句形成的组运行聚集函数计算每一组的值;最后用having 子句去掉不符合条件的组。
    • having 子句中的每一个元素也必须出现在select列表中(这一条很重要,又是坑了我半天)。有些数据库例外,如oracle.
    • having子句和where子句都可以用来设定限制条件以使查询结果满足一定的条件限制。
    • having子句限制的是组,而不是行。where子句中不能使用聚集函数,而having子句中可以。

    5、mysql中变量申明定义

    • DECLARE variable_name datatype(size) DEFAULT default_value;  此处声明的相当于一个局部变量 ,在end 之后便失效。声明多个变量:DECLARE x, y INT DEFAULT 0 ;
    • SET @num=19;   SET @num:=19;    //一个是"="进行赋值;另一个是使用“:=”进行赋值。此处的session变量不需要声明,mysql会自动根据值类型来确定类型,这种变量要在变量名称前面加上“@”符号,叫做会话变量,代表整个会话过程他都是有作用的,这个有点类似于全局变量一样。这种变量用途比较广,因为只要在一个会话内(就是某个应用的一个连接过程中),这个变量可以在被调用的存储过程或者代码之间共享数据。
    • select @num:=1; 或 select @num:=字段名 from 表名 where ……    //比如:SELECT @num:= COUNT(*) FROM blog_note;
    • 注意上面两种赋值符号,使用set时可以用“=”或“:=”,但是使用select时必须用“:=赋值”。

      

  • 相关阅读:
    受益一生的15个学习习惯
    如何在工作的头三年里让自己变得强大
    linux定时执行脚本
    SpringMVC基础入门
    Spring与Quartz的整合实现定时任务调度[转]
    强肝保肝养肝4大食物
    Spring官网jar包下载方法
    tomcat管理端的页面安全措施
    Struts2 Action 动态传参数
    Java之控制反转和依赖注入
  • 原文地址:https://www.cnblogs.com/sdll/p/7521423.html
Copyright © 2020-2023  润新知