思路:hive数据插入pre表(根据pre表分区字段数量来决定交换多少个分区),再新建pre表插入数据到mid表,最后mid表和目标表分区交换。
hive数仓->pre表->mid表->目标表
注意:pre表的分区字段需要单独加上索引,会加快pre表数据插入mid表的速度。
pre表、mid表、目标表三者表结构一定要相同,且pre表、mid表不能为分区表。
具体步骤:
第一步:统计pre表开始日期
第二步:统计pre表结束日期
第三步:删除mid表(如果存在,需要先删除)
第四步:开始创建mid表
第五步:删除mid表分区
第六步:统计pre表分区数据量
循环开始
判断pre表分区数据量是否大于 0
pre表分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表
第八步:插入数据过程(pre表->mid表)
第九步:目标表分区交换
pre表分区数据量小于等于 0 ,不继续执行循环内容
循环结束
第十步:删除mid表
第十一步:插入日志
日志表建表语句:
CREATE TABLE procedure_execute_detail_log (
id INT AUTO_INCREMENT PRIMARY KEY,
tablename_schema varchar(100) DEFAULT NULL COMMENT '表所属数据库名',
tablename varchar(100) DEFAULT NULL COMMENT '目标表名称',
partition_field varchar(100) DEFAULT NULL COMMENT '分区字段',
msg LONGTEXT DEFAULT NULL COMMENT '存储过程返回信息out',
procedure_execute_date DATE DEFAULT NULL COMMENT '存储过程-执行日期',
procedure_execute_start_date datetime DEFAULT NULL COMMENT '存储过程执行-开始时间',
procedure_execute_end_date datetime DEFAULT NULL COMMENT '存储过程执行-结束时间',
INDEX `index_procedure_execute_date`(`procedure_execute_date`) USING BTREE,
INDEX `index_tablename`(`tablename`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储过程日志表'
-- SELECT LAST_INSERT_ID(); -- 查看当前序列
-- ALTER TABLE students AUTO_INCREMENT = 1001; --重置自增序列
-- select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名称' limit 1
代码执行结果:
注意:此存储过程遇到报错,直接退出程序,不会继续执行!!!!!!!
第一步:统计pre表开始日期 分区交换开始日期:2023-11-01 =>用时:00:00:00.000000
第二步:统计pre表结束日期 分区交换结束日期:2023-11-29 =>用时:00:00:00.000000
第三步:删除mid表 =>用时:00:00:00.000000
第四步:开始创建mid表 =>用时:00:00:11.000000
第五步:删除mid表分区 =>用时:00:00:04.000000
循环开始..........
第1次循环
第六步:统计pre表2023-11-29分区数据量 =>用时:00:00:00.000000
pre表2023-11-29分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:04.000000
第九步:目标表分区交换 =>用时:00:00:01.000000
第2次循环
第六步:统计pre表2023-11-28分区数据量 =>用时:00:00:00.000000
pre表2023-11-28分区数据量小于等于 0 ,不继续执行循环内容
第3次循环
第六步:统计pre表2023-11-27分区数据量 =>用时:00:00:00.000000
pre表2023-11-27分区数据量小于等于 0 ,不继续执行循环内容
第4次循环
第六步:统计pre表2023-11-26分区数据量 =>用时:00:00:00.000000
pre表2023-11-26分区数据量小于等于 0 ,不继续执行循环内容
第5次循环
第六步:统计pre表2023-11-25分区数据量 =>用时:00:00:00.000000
pre表2023-11-25分区数据量小于等于 0 ,不继续执行循环内容
第6次循环
第六步:统计pre表2023-11-24分区数据量 =>用时:00:00:00.000000
pre表2023-11-24分区数据量小于等于 0 ,不继续执行循环内容
第7次循环
第六步:统计pre表2023-11-23分区数据量 =>用时:00:00:00.000000
pre表2023-11-23分区数据量小于等于 0 ,不继续执行循环内容
第8次循环
第六步:统计pre表2023-11-22分区数据量 =>用时:00:00:00.000000
pre表2023-11-22分区数据量小于等于 0 ,不继续执行循环内容
第9次循环
第六步:统计pre表2023-11-21分区数据量 =>用时:00:00:00.000000
pre表2023-11-21分区数据量小于等于 0 ,不继续执行循环内容
第10次循环
第六步:统计pre表2023-11-20分区数据量 =>用时:00:00:00.000000
pre表2023-11-20分区数据量小于等于 0 ,不继续执行循环内容
第11次循环
第六步:统计pre表2023-11-19分区数据量 =>用时:00:00:00.000000
pre表2023-11-19分区数据量小于等于 0 ,不继续执行循环内容
第12次循环
第六步:统计pre表2023-11-18分区数据量 =>用时:00:00:00.000000
pre表2023-11-18分区数据量小于等于 0 ,不继续执行循环内容
第13次循环
第六步:统计pre表2023-11-17分区数据量 =>用时:00:00:00.000000
pre表2023-11-17分区数据量小于等于 0 ,不继续执行循环内容
第14次循环
第六步:统计pre表2023-11-16分区数据量 =>用时:00:00:00.000000
pre表2023-11-16分区数据量小于等于 0 ,不继续执行循环内容
第15次循环
第六步:统计pre表2023-11-15分区数据量 =>用时:00:00:00.000000
pre表2023-11-15分区数据量小于等于 0 ,不继续执行循环内容
第16次循环
第六步:统计pre表2023-11-14分区数据量 =>用时:00:00:00.000000
pre表2023-11-14分区数据量小于等于 0 ,不继续执行循环内容
第17次循环
第六步:统计pre表2023-11-13分区数据量 =>用时:00:00:00.000000
pre表2023-11-13分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:06.000000
第九步:目标表分区交换 =>用时:00:00:01.000000
第18次循环
第六步:统计pre表2023-11-12分区数据量 =>用时:00:00:00.000000
pre表2023-11-12分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:00.000000
第19次循环
第六步:统计pre表2023-11-11分区数据量 =>用时:00:00:00.000000
pre表2023-11-11分区数据量小于等于 0 ,不继续执行循环内容
第20次循环
第六步:统计pre表2023-11-10分区数据量 =>用时:00:00:00.000000
pre表2023-11-10分区数据量小于等于 0 ,不继续执行循环内容
第21次循环
第六步:统计pre表2023-11-09分区数据量 =>用时:00:00:00.000000
pre表2023-11-09分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:01.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:01.000000
第22次循环
第六步:统计pre表2023-11-08分区数据量 =>用时:00:00:00.000000
pre表2023-11-08分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:01.000000
第23次循环
第六步:统计pre表2023-11-07分区数据量 =>用时:00:00:00.000000
pre表2023-11-07分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:00.000000
第24次循环
第六步:统计pre表2023-11-06分区数据量 =>用时:00:00:00.000000
pre表2023-11-06分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:01.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:00.000000
第25次循环
第六步:统计pre表2023-11-05分区数据量 =>用时:00:00:00.000000
pre表2023-11-05分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:04.000000
第九步:目标表分区交换 =>用时:00:00:00.000000
第26次循环
第六步:统计pre表2023-11-04分区数据量 =>用时:00:00:00.000000
pre表2023-11-04分区数据量小于等于 0 ,不继续执行循环内容
第27次循环
第六步:统计pre表2023-11-03分区数据量 =>用时:00:00:00.000000
pre表2023-11-03分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:01.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:01.000000
第28次循环
第六步:统计pre表2023-11-02分区数据量 =>用时:00:00:00.000000
pre表2023-11-02分区数据量小于等于 0 ,不继续执行循环内容
第29次循环
第六步:统计pre表2023-11-01分区数据量 =>用时:00:00:00.000000
pre表2023-11-01分区数据量大于 0 ,继续执行循环内容
第七步:truncate mid表 =>用时:00:00:00.000000
第八步:插入数据过程(pre表->mid表) =>用时:00:00:03.000000
第九步:目标表分区交换 =>用时:00:00:00.000000
循环结束..........
第十步:删除mid表
全部代码:
/*
调用方式
call exchange_partition_table('fopdata','test_partitions','p_day',@msg);
select @msg;
*/
/*
步骤 代码 说明
步骤1 START TRANSACTION; 开始一个事务
步骤2 DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 声明一个异常处理程序,当发生异常时回滚事务
步骤3 SAVEPOINT sp1; 创建一个保存点,用于回滚到这个点
步骤4 INSERT INTO table_name (column1, column2, …) VALUES (value1, value2, …); 执行需要回滚的数据库操作,例如插入一条数据
步骤5 RELEASE SAVEPOINT sp1; 释放保存点,表示我们确认这个点之后的操作都是正确的
步骤6 COMMIT; 提交事务,表示整个事务执行完毕
步骤7 END; 存储过程结束
CREATE TABLE procedure_execute_detail_log (
id INT AUTO_INCREMENT PRIMARY KEY,
tablename_schema varchar(100) DEFAULT NULL COMMENT '表所属数据库名',
tablename varchar(100) DEFAULT NULL COMMENT '目标表名称',
partition_field varchar(100) DEFAULT NULL COMMENT '分区字段',
msg LONGTEXT DEFAULT NULL COMMENT '存储过程返回信息out',
procedure_execute_date DATE DEFAULT NULL COMMENT '存储过程-执行日期',
procedure_execute_start_date datetime DEFAULT NULL COMMENT '存储过程执行-开始时间',
procedure_execute_end_date datetime DEFAULT NULL COMMENT '存储过程执行-结束时间',
INDEX `index_procedure_execute_date`(`procedure_execute_date`) USING BTREE,
INDEX `index_tablename`(`tablename`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存储过程日志表'
-- SELECT LAST_INSERT_ID(); -- 查看当前序列
-- ALTER TABLE students AUTO_INCREMENT = 1001; --重置自增序列
-- select AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = '数据库名称' AND TABLE_NAME = '表名称' limit 1
*/
DROP PROCEDURE IF EXISTS exchange_partition_table;
DELIMITER $$
CREATE PROCEDURE `exchange_partition_table`(
IN tablename_schema VARCHAR (50), -- 表所属数据库名
IN tablename VARCHAR (50), -- 目标表名称
IN partition_field VARCHAR (50), -- 分区字段
OUT msg LONGTEXT) -- 输出日志 @msg
BEGIN
DECLARE error_code VARCHAR(50) DEFAULT ''; -- 错误代码
DECLARE error_msg TEXT; -- 报错信息
DECLARE date_cycles int DEFAULT 1; -- 循环次数
DECLARE error_location VARCHAR(50) DEFAULT ''; -- 错误定位编号
DECLARE errorcontext_1 VARCHAR(2000) DEFAULT ''; -- 报错原因
DECLARE start_second_time VARCHAR(200) DEFAULT ''; -- 开始时间
DECLARE end_second_time VARCHAR(200) DEFAULT ''; -- 结束时间
DECLARE diffenrence_second_time_1 VARCHAR(200) DEFAULT ''; -- 程序用时多少
DECLARE procedure_execute_date VARCHAR(200) DEFAULT ''; -- 存储过程-执行日期
DECLARE procedure_execute_start_date VARCHAR(200) DEFAULT '';-- 存储过程执行-开始时间
DECLARE procedure_execute_end_date VARCHAR(200) DEFAULT '';-- 存储过程执行-结束时间
DECLARE i INT DEFAULT 0;
DECLARE p_cnt INT DEFAULT 0;
DECLARE p_date VARCHAR(20);
DECLARE p_sql VARCHAR(2000);
DECLARE create_tab VARCHAR(2000);
DECLARE table_mid VARCHAR(2000);
DECLARE remove_partition VARCHAR(2000);
DECLARE drop_tab VARCHAR(2000);
DECLARE insert_log LONGTEXT;
-- CONTINUE EXIT
-- DECLARE CONTINUE HANDLER FOR SQLEXCEPTION -- 异常信息处理
DECLARE EXIT HANDLER FOR SQLEXCEPTION -- 抛异常,就退出程序 ,报错才会执行以下内容
BEGIN
-- 获取异常code,异常信息
GET DIAGNOSTICS CONDITION 1
error_code = RETURNED_SQLSTATE, error_msg= MESSAGE_TEXT;
SET msg = CONCAT_ws('',msg,'\n',errorcontext_1,'\n报错信息: 错误编号:',error_code,', 内容:',error_msg);
-- select msg;
-- 报错也需要继续插入日志
SET procedure_execute_end_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s'); -- 存储过程执行-结束时间
SET insert_log = CONCAT_ws('','insert into ',tablename_schema,'.procedure_execute_detail_log (tablename_schema,tablename,partition_field,msg,procedure_execute_date,procedure_execute_start_date,procedure_execute_end_date)
values("',tablename_schema,'","',tablename,'","',partition_field,'","',msg,'",DATE_FORMAT("'
,procedure_execute_date,'","%Y-%m-%d"),DATE_FORMAT("'
,procedure_execute_start_date,'","%Y-%m-%d %H:%i:%s"),DATE_FORMAT("'
,procedure_execute_end_date,'","%Y-%m-%d %H:%i:%s"));');
SET @dt = insert_log;
PREPARE stmt FROM @dt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
commit;
-- select insert_log;
-- ROLLBACK;
-- RELEASE SAVEPOINT sp1;
-- commit;
END;
/*
-- 注意 执行分区交换,pre表 p_day字段必须加索引,否则会执行很慢。
*/
SET procedure_execute_date=DATE_FORMAT(now(),'%Y-%m-%d'); -- 存储过程-执行日期 '2023-12-04'
SET procedure_execute_start_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s');-- 存储过程执行-开始时间
SET msg = CONCAT('注意:此存储过程遇到报错,直接退出程序,不会继续执行!!!!!!!');
SET msg = CONCAT(msg,'\n第一步:统计pre表开始日期');
SET errorcontext_1 = CONCAT('报错位置:执行第一步失败'); -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('select min(',partition_field,') into @pre_start_time from ', CONCAT(tablename_schema,'.',tablename), '_pre ;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第一步用时
SET msg = CONCAT(msg,'\t分区交换开始日期:',@pre_start_time,' =>用时:',diffenrence_second_time_1);
SET msg = CONCAT(msg,'\n第二步:统计pre表结束日期');
SET errorcontext_1 = CONCAT('报错位置:执行第二步失败'); -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('select max(',partition_field,') into @pre_end_time from ', CONCAT(tablename_schema,'.',tablename), '_pre ;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第二步用时
SET msg = CONCAT(msg,'\t分区交换结束日期:',@pre_end_time,' =>用时:',diffenrence_second_time_1);
-- 循环次数
-- 日期格式:yyyy-mm-dd 判断 -- 日期格式: yyyy-mm判断
if length(@pre_end_time)=10 then
set date_cycles=datediff(@pre_end_time,@pre_start_time)+1;
elseif length(@pre_end_time)=7 then
set date_cycles=PERIOD_DIFF(REPLACE(@pre_end_time,'-',''),REPLACE(@pre_start_time,'-',''))+1;
else
SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
end if;
SET msg = CONCAT(msg,'\n第三步:删除mid表');
set table_mid = CONCAT(tablename, '_mid');
SET errorcontext_1 = CONCAT('报错位置:执行第三步失败'); -- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET create_tab = CONCAT('drop table IF EXISTS ', CONCAT(tablename_schema,'.',table_mid),';');
SET @s = create_tab;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第三步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n第四步:开始创建mid表');
set table_mid = CONCAT(tablename, '_mid');
SET errorcontext_1 = CONCAT('报错位置:执行第四步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET create_tab = CONCAT('create table IF NOT EXISTS ', CONCAT(tablename_schema,'.',table_mid), ' like ',CONCAT(tablename_schema,'.',tablename),';');
SET @s = create_tab;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第四步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n第五步:删除mid表分区');
SET errorcontext_1 = CONCAT('报错位置:执行第五步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET remove_partition = CONCAT('alter table ', CONCAT(tablename_schema,'.',table_mid), ' remove partitioning;');
SET @s = remove_partition;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第五步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n循环开始..........');
WHILE i < date_cycles DO
if length(@pre_end_time)=10 then -- yyyy-mm-dd
SET p_date = DATE_FORMAT(DATE_SUB(@pre_end_time, INTERVAL i DAY), '%Y-%m-%d');
elseif length(@pre_end_time)=7 then -- yyyy-mm
set p_date = DATE_FORMAT(concat_ws('',PERIOD_ADD(REPLACE(@pre_end_time,'-',''), -i),'01'),'%Y-%m');
else
SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
end if;
SET msg = CONCAT(msg,'\n\t\t\t第',i+1,'次循环');
SET msg = CONCAT(msg,'\n\t\t\t第六步:统计pre表',p_date,'分区数据量');
SET errorcontext_1 = CONCAT('报错位置:执行第六步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('SELECT COUNT(1) INTO @cnt FROM ', CONCAT(tablename_schema,'.',tablename), '_pre WHERE ',partition_field,' = ?;');
SET @s = p_sql;
SET @p1 = p_date;
PREPARE stmt FROM @s;
EXECUTE stmt USING @p1;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第六步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1);
-- 判断分区数据量大于 0
SET p_cnt = @cnt;
IF p_cnt > 0 THEN
SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量大于 0 ,继续执行循环内容');
SET msg = CONCAT(msg,'\n\t\t\t\t\t\t\t第七步:truncate mid表');
SET errorcontext_1 = CONCAT('报错位置:执行第七步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('TRUNCATE TABLE ', CONCAT(tablename_schema,'.',table_mid), ';');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第七步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n\t\t\t\t\t\t\t第八步:插入数据过程(pre表->mid表)');
SET errorcontext_1 = CONCAT('报错位置:执行第八步失败');
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('INSERT INTO ', CONCAT(tablename_schema,'.',table_mid), ' SELECT * FROM ', CONCAT(tablename_schema,'.',tablename), '_pre WHERE ', CONCAT(tablename_schema,'.',tablename), '_pre.',partition_field,' = ?;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt USING @p1;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第八步用时
/*
-- 以下判断作用是分区名称p20231101,去除日期-
if length(@pre_end_time)=10 then -- yyyy-mm-dd
SET p_date = DATE_FORMAT(DATE_SUB(@pre_end_time, INTERVAL i DAY), '%Y%m%d'); -- 分区名称
elseif length(@pre_end_time)=7 then -- yyyy-mm
set p_date = DATE_FORMAT(concat_ws('',PERIOD_ADD(REPLACE(@pre_end_time,'-',''), -i),'01'),'%Y%m'); -- 分区名称
else
SET msg = CONCAT(msg,'\n输入参数分区字段错误!!!!!');
end if;
*/
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n\t\t\t\t\t\t\t第九步:目标表分区交换');
SET errorcontext_1 = CONCAT('报错位置:执行第九步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET p_sql = CONCAT('ALTER TABLE ', CONCAT(tablename_schema,'.',tablename), ' EXCHANGE PARTITION p', replace(p_date,'-',''), ' WITH TABLE ', CONCAT(tablename_schema,'.',table_mid), ' WITHOUT validation;');
SET @s = p_sql;
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第九步用时
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1);
else
if date_cycles=i+1 then
SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量小于等于 0 ,不继续执行循环内容,退出循环');
else
SET msg = CONCAT(msg,'\n\t\t\t\t\tpre表',p_date,'分区数据量小于等于 0 ,不继续执行循环内容');
end if;
END IF;
SET i = i + 1;
END WHILE;
SET msg = CONCAT(msg,'\n循环结束..........');
SET msg = CONCAT(msg,'\n第十步:删除mid表');
SET errorcontext_1 = CONCAT('报错位置:执行第十步失败');-- 用于定位报错位置
set start_second_time=unix_timestamp(); -- 开始时间
SET drop_tab = CONCAT('drop table IF EXISTS ', CONCAT(tablename_schema,'.',table_mid), ';');
SET @dt = drop_tab;
PREPARE stmt FROM @dt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
set end_second_time=unix_timestamp(); -- 结束时间
set diffenrence_second_time_1 = sec_to_time(end_second_time-start_second_time); -- 第十步用时
SET errorcontext_1 ='';-- 以上步骤全部执行成功,将报错位置置成空值
SET msg = CONCAT(msg,' =>用时:',diffenrence_second_time_1,'\n所有步骤执行成功。。。。。。。');
select msg;-- 打印返回信息
-- 第十一步:存储过程返回信息插入日志procedure_execute_detail_log表
SET errorcontext_1 = CONCAT('报错位置:执行第十一步失败');-- 用于定位报错位置
SET procedure_execute_end_date=DATE_FORMAT(now(),'%Y-%m-%d %H:%i:%s'); -- 存储过程执行-结束时间
SET insert_log = CONCAT_ws('','insert into ',tablename_schema,'.procedure_execute_detail_log (tablename_schema,tablename,partition_field,msg,procedure_execute_date,procedure_execute_start_date,procedure_execute_end_date)
values("',tablename_schema,'","',tablename,'","',partition_field,'","',msg,'",DATE_FORMAT("'
,procedure_execute_date,'","%Y-%m-%d"),DATE_FORMAT("'
,procedure_execute_start_date,'","%Y-%m-%d %H:%i:%s"),DATE_FORMAT("'
,procedure_execute_end_date,'","%Y-%m-%d %H:%i:%s"));');
SET @dt = insert_log;
PREPARE stmt FROM @dt;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
commit;
END
$$
DELIMITER;