这是正确的存储过程写法,可以成功执行,相比较上图的报错,增加了DELIMITER,简单解释下这个命令的用途,在MySQL中每行命令都是用“;”结尾,回车后自动执行,在存储过程中“;”往往不代表指令结束,马上运行,而DELIMITER原本就是“;”的意思,因此用这个命令转换一下“;”为"$$",这样只有收到"$$"才认为指令结束可以执行
delimiter就是告诉mysql解释器,该段命令是否已经结束了,是否可以执行了。
默认情况下,delimiter是分号;,遇到分号就执行。
后面的双美元符号 就是告诉mysql,遇到双美元符号再执行这改变了MySQL命令的默认分隔符,使得存储过程中可以包含多个SQL语句。
-- 定义分隔符:`DELIMITER`。这改变了MySQL命令的默认分隔符,
-- 使得存储过程中可以包含多个SQL语句。
DELIMITER $$
-- 选择数据库meteorological:USE `meteorological`。
-- 这指示MySQL使用名为meteorological的数据库。
USE `meteorological`$$
-- **删除如果已存在的存储过程**:DROP PROCEDURE IF EXISTS `StatisticsForDay1`。
如果存储过程`StatisticsForDay1`已经存在,则删除它。
DROP PROCEDURE IF EXISTS `StatisticsForDay1`$$
-- ??创建存储过程??:CREATE DEFINER=`root@`%` PROCEDURE `StatisticsForDay1`()
CREATE DEFINER=`root`@`%` PROCEDURE `StatisticsForDay1`()
BEGIN
-- **声明变量??:声明了两个变量,sql_str用于存储SQL语句,
-- `CURDATE`用于存储当前日期减去一天的值。
DECLARE sql_str VARCHAR(1000);
DECLARE CURDATE VARCHAR(10);
-- ??获取昨天的日期??:使用‘SELECT DATE_ADD(CURRENT_DATE,INTERVAL ?1 DAY)INTO CURDATE;
-- ‘获取昨天的日期,并将其存储在变量‘CURDATE‘中。
SELECT DATE_ADD(CURRENT_DATE,INTERVAL -1 DAY) INTO CURDATE;
-- ??构建并执行删除语句??:构建一个SQL语句来删除`bn_day_sum`表中昨天的所有记录,并执行它。
SET sql_str = CONCAT('
DELETE FROM bn_day_sum
WHERE `date` LIKE ''',CURDATE,'%''');
SELECT sql_str;
SET @sql = sql_str;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- ??构建并执行插入语句??:构建一个SQL语句来从‘bn_hour_sum‘表中选择昨天的数据,
-- 并将其插入到`bn_day_sum`表中。然后执行这个语句。
SET sql_str = CONCAT('
INSERT INTO bn_day_sum(device,`group`,num,`date`,`max_value`,max_value_time,
`min_value`,`min_value_time`,sum_value,count_num,avg_num,warn_count,`time`)
SELECT device,`group`,num,DATE(`hour`) `Date`,
MAX(`max_value`) `MaxValue`,NULL MaxValueTime,
MIN(`min_value`) `MinValue`,NULL MinValueTime,
SUM(`sum_value`) SumValue,SUM(count_num) CountNum,
SUM(`sum_value`)/SUM(count_num) AvgNum,
SUM(`warn_count`) WarnCount,CURRENT_TIMESTAMP Time
FROM bn_hour_sum
WHERE `hour` LIKE ''',CURDATE,'%''
GROUP BY device,`group`,num, DATE(`hour`) ');
SELECT sql_str;
SET @sql = sql_str;
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 尖凤平谷统计 10101,10102,10103,10104 从10144得到
SELECT DATE(CURDATE) INTO @curDate;
-- ??创建临时表并插入数据??:创建一个临时表(如果它不存在),并插入一些统计数据,
-- 这些数据基于对‘bn_hour_sum‘表中特定记录的筛选和计算。
CREATE TEMPORARY TABLE IF NOT EXISTS t1(Device VARCHAR(32),
`Group` VARCHAR(32),Num VARCHAR(64),s INT,p INT,f INT,v INT);
-- ??将数据插入到bn_day_sum表中??:最后,将临时表中的数据插入到‘bn_day_sum‘表中。
INSERT INTO t1 SELECT device,`group`,num,
SUM(CASE spfv WHEN 's' THEN `max_value` - `min_value` ELSE 0 END) s,
SUM(CASE spfv WHEN 'p' THEN `max_value` - `min_value` ELSE 0 END) p,
SUM(CASE spfv WHEN 'f' THEN `max_value` - `min_value` ELSE 0 END) f,
SUM(CASE spfv WHEN 'v' THEN `max_value` - `min_value` ELSE 0 END) v
FROM
bn_hour_sum
WHERE DATE(`hour`) = @curDate AND num='10144'
GROUP BY device,`group`,num;
-- 将临时表t1中的数据插入到bn_day_sum表中。对于不同的设备(10101、10102、10103、10104),
-- 它们的数据来自相同的临时表t1,但插入到bn_day_sum表中的数据有所不同。例如,
-- 对于设备'10101',它的max_value、min_value等数据都设置为0,
-- 并且从临时表t1中选择了s列作为其sum_value。
INSERT INTO bn_day_sum(device,`group`,num,`date`,`max_value`,max_value_time,
`min_value`,min_value_time,sum_value,count_num,avg_num,warn_count,TIME)
SELECT t1.device,t1.`group`,'10101',@curDate,0,NULL,0,NULL,t1.s,0,0,0,
CURRENT_TIMESTAMP
FROM t1;
INSERT INTO bn_day_sum(device,`group`,num,`date`,`max_value`,max_value_time,
`min_value`,min_value_time,sum_value,count_num,avg_num,warn_count,TIME)
SELECT t1.device,t1.`group`,'10102',@curDate,0,NULL,0,NULL,t1.p,0,0,0,
CURRENT_TIMESTAMP FROM t1;
INSERT INTO bn_day_sum(device,`group`,num,`date`,`max_value`,max_value_time,
`min_value`,min_value_time,sum_value,count_num,avg_num,warn_count,TIME)
SELECT t1.device,t1.`group`,'10103' ,@curDate,0,NULL,0,NULL,t1.f,0,0,0,
CURRENT_TIMESTAMP FROM t1;
INSERT INTO bn_day_sum(device,`group`,num,`date`,`max_value`,max_value_time,
`min_value`,min_value_time,sum_value,count_num,avg_num,warn_count,TIME)
SELECT t1.device,t1.`group`,'10104',@curDate,0,NULL,0,NULL,t1.v,0,0,0,
CURRENT_TIMESTAMP FROM t1;
-- 最后,这段代码删除了临时表t1。
-- 总的来说,这段存储过程将之前计算得到的统计数据(针对不同设备)从临时表t1中提取出来,
-- 并插入到bn_day_sum表中,最后清理了临时表。
DROP TEMPORARY TABLE t1;
END$$
DELIMITER ;