问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

MySQL如何每个月自动创建一张表,以年月做为表名

发布网友 发布时间:2022-05-02 09:45

我来回答

1个回答

热心网友 时间:2022-05-02 11:14

  我正好有楼主类似的需求,每个季度为几个表增加一个分区,表的基本名称是在一个叫设备类型的表里,每天计划执行一个过程,在过程里从系统表中判断是否已经创建了相关的分区,如果没创建就创建它
楼主可以参考一下,记得在my.ini 文件里配置event_scheler=on

/**
定时每天检查各个设备类型的历史数据表,如果历史数据表的所在分区已经
接近当前日期,则为此设备类型追加分区
*/
 
-- 得到按月分区的日期值
delimiter ;
drop function if exists fnGetPartitionDateForMonth; 
delimiter ;;
create function fnGetPartitionDateForMonth() returns INT
begin
    declare v_today datetime default date_add(now(), INTERVAL 2 month);
    return year(v_today) * 100 + month(v_today);
end;;
 
-- 得到按季度分区的日期值
delimiter ;
drop function if exists fnGetPartitionDateForQuarter;
delimiter ;;
create function fnGetPartitionDateForQuarter() returns int
begin
    declare v_today datetime default date_add(now(), interval 3 month);
    declare v_month int;
     
    set v_month = month(v_today);
    if v_month = 1 or v_month = 2 or v_month = 3 then 
        set v_today = DATE_ADD(v_today, INTERVAL (4 - v_month) month);
    elseif v_month = 4 or v_month = 5 or v_month = 6 THEN
        set v_today = DATE_ADD(v_today, INTERVAL (7 - v_month) month);
    elseif v_month = 7 or v_month = 8 or v_month = 9 THEN
        set v_today = date_add(v_today, INTERVAL (10 - v_month) month);
    ELSE
        set v_today = date_add(v_today, INTERVAL (13 - v_month) month);
    end if;
     
    return year(v_today) * 100 + month(v_today);
end;;
 
-- 得到按半年分区的日期值
delimiter ;
drop function if exists fnGetPartitionDateForHalfYear;
delimiter ;;
create function fnGetPartitionDateForHalfYear() returns int
begin
    declare v_today datetime default date_add(now(), interval 6 month);
    declare v_month int;
     
    set v_month = month(v_today);
     
    if v_month <= 6 THEN
        set v_today = date_add(v_today, INTERVAL (7 - v_month) month);
    else
        set v_today = DATE_ADD(v_today, INTERVAL (13 - v_month) month);
    end if;
     
    return year(v_today) * 100 + month(v_today);
end;;
 
-- 维护按年分区
delimiter ;
drop function if exists fnGetPartitionDateForYear;
delimiter ;;
create function fnGetPartitionDateForYear() returns int
begin
    declare v_today datetime default date_add(now(), INTERVAL 2 year);
    return year(v_today) * 100;
end;;
 
 
delimiter ;
drop procere if exists spMaintainPartitions;
delimiter ;;
create procere spMaintainPartitions()
BEGIN
     
    declare v_sql varchar(2000);
    declare v_cnt int;
    declare v_deviceTypeId int;
    declare v_tablename varchar(50);
    declare v_tablename_analog varchar(50);
    declare v_tablename_digital varchar(50);
    declare v_partitionType int;
    declare v_fileDir varchar(1000);
    declare v_tablenames varchar(1000) default '';
    declare v_intDate int;
    declare v_partitionName varchar(100);
    declare done int default 0;
    declare c_deviceType cursor 
        for select Id, TableName, PartitionType, DataFileDir
                from tbDeviceType 
                where Generated = 1;
    declare continue handler for not found set done = 1;
     
    insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`)
            Values(Now(), 'spMaintainPartitions start......');
     
    open c_deviceType;
    deviceType_loop: LOOP
         
        fetch c_deviceType into v_deviceTypeId, v_tablename, v_partitionType, v_fileDir;
         
        set v_fileDir = replace(v_fileDir, '\\', '/');
        if locate(':', v_fileDir) > 0 and locate(':/', v_fileDir) = 0 then
            set v_fileDir = replace(v_fileDir, ':', ':/');
        end if;
         
        if done = 1 then 
            leave deviceType_loop;
        end if;
         
        set v_intDate = null;
        if v_partitionType = 1 then 
            set v_intDate = fnGetPartitionDateForMonth();
        ELSEIF v_partitionType = 2 THEN
            set v_intDate = fnGetPartitionDateForQuarter();
        ELSEIF v_partitionType = 3 then 
            set v_intDate = fnGetPartitionDateForHalfYear();
        elseif v_partitionType = 4 then 
            set v_intDate = fnGetPartitionDateForYear();
        end if;
         
        if v_intDate is null then
            insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`) 
                    values(Now(), Concat('DeviceTypeId = ', cast(v_deviceTypeId As char(10)), ' did not define paritition schele'));
        else 
             
            set v_partitionName = concat('p', cast(v_intDate as char(6)));
             
            -- 模拟量表
            set v_tablename_analog = concat(v_tablename, '_Analog');
            select count(*) into v_cnt
                from information_schema.`TABLES` where `TABLE_SCHEMA` = database() and `table_name` = v_tablename_analog;
             
 
            if v_cnt > 0 then
 
                select count(*) into v_cnt
                from 
                    information_schema.`PARTITIONS` 
                where 
                    TABLE_SCHEMA = database() and table_name = v_tablename_analog and partition_name = v_partitionName;
                 
                if v_cnt = 0 then
                    set v_sql = CONCAT('alter table ', v_tablename_analog, ' add partition (partition ', v_partitionName, ' values less than (', cast(v_intDate as char(6)), ') data directory = ''', v_fileDir, ''' index directory = ''', v_fileDir , ''')');
                    insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`)
                            Values(Now(), concat('sql = ''', v_sql));
                     
                    set @sql = v_sql;
                    prepare cmd from @sql;
                    execute cmd;
                    deallocate prepare cmd;
                     
                    insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`) 
                        values(Now(), concat('execute complete: ', v_sql));
                end if;
            end if;
             
            -- 数字量表
            set v_tablename_digital = concat(v_tablename, '_Digital');
            select count(*) into v_cnt
                from information_schema.`TABLES` where `TABLE_SCHEMA` = database() and `table_name` = v_tablename_digital;
             
            if v_cnt > 0 then
 
                select count(*) into v_cnt
                from 
                    information_schema.`PARTITIONS`
                where 
                    TABLE_SCHEMA = database() and table_name = v_tablename_digital and partition_name = v_partitionName;
                 
                if v_cnt = 0 then 
                    set v_sql = CONCAT('alter table ', v_tablename_digital, ' add partition (partition ', v_partitionName, ' values less than (', cast(v_intDate as char(6)), ') data directory = ''', v_fileDir, ''' index directory = ''', v_fileDir , ''')');
                     
                    insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`)
                            Values(Now(), concat('sql = ''', v_sql));
                     
                    set @sql = v_sql;
                    prepare cmd from @sql;
                    execute cmd;
                    deallocate prepare cmd;
                     
                    insert into tbPartitionMaintainLog(`CreatedDateTime`, `LogContent`) 
                        values(Now(), concat('execute complete: ', v_sql));
                     
                end if;
            end if;
             
        end if;
         
    end loop deviceType_loop;
    close c_deviceType;
     
END;;
 
delimiter ;
 
drop event if exists e_DataPartitionMaintain;
create event e_DataPartitionMaintain
    on SCHEDULE every 60 Second
    on completion PRESERVE
    do call spMaintainPartitions();
 
set global event_scheler = on;

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
Request对象语法 9,django中request对象 塞尔达传说时之笛火之神殿Boss房间怎么去 ...的圆形地方怎么上去?打完BOSS后才发现没去过,但我 榆中兴隆山旅游路线 ...兴隆山校区到哪个公交车站最近?应该怎么乘公交车?打车的话得多少钱... 从般若寺到兴隆山法院怎么坐公交车,最快需要多久 那些属于国有经济,哪些属于集体经济 ...丢手机,生病,丢工作,怎么转运啊,谁能告诉我,我快疯了 阴历十月又叫什么月 求泡沫纸叠玫瑰花的教程!叠如图所示的!! 泡沫纸 叠玫瑰花 泡沫玫瑰花怎么叠 EVA泡沫海绵玫瑰花怎么做 华为手机突然只有下面亮了,其他地方暗 华为手机屏幕的一亮一暗的是怎么回事? 用微波炉烤肉架子铺锡纸吗 近代朝鲜文学是什么? 日治时期的朝鲜爱国诗人 朝鲜16世纪中叶有哪些杰出的爱国主义诗歌? 朝鲜有哪些优秀的诗人和古诗 韩国教授要求将朝鲜族诗人国籍改成韩国,这事你怎么看? 你是如何看待韩国教授要求将朝鲜族诗人国籍改成韩国这件事的? 韩国最有名的诗人是谁? 身份证和银行卡都丢了,该怎么去报失和补办银行卡? 韩国教授要求将哪位朝鲜族诗人国籍改成韩国? 身份证银行卡都丢了怎么补办新的银行卡 超大键盘的手机,屏幕是横屏的老人机 尹东柱到底是中国诗人还是韩国诗人 联想手机键盘怎么切换大键盘 腰椎间盘突出轻微疼痛怎么办 轻微的椎间盘突出怎么锻炼得到恢复 腰椎间盘损伤怎么办 请问轻度腰间盘突出自己怎样锻炼恢复? 轻微腰间盘突出怎么恢复? 腰椎间盘只是轻度突出,通过适当的运动能否恢复。 轻微腰间盘突出可以做些什么康复运动 MacOS电脑上有啥好用的防干扰窗口管理软件?HazeOver怎么样?好用不? 求mac上的双窗口管理工具Fenetre中文汉化版! 腰椎间盘突出轻微的能治好吗 轻度腰椎间盘突出如何治疗? 怎么下载窗口管理器Moom?求分享 怎样设置 Mac 系统窗口最小化隐藏的第三种效果 请教下各位兄台,苹果电脑上有什么好用的mac窗口切换工具?简单实用的?witch怎么样? 求个窗口管理神器Fenetre mac破解版下载 机关事业退休认证方法是什么 被取保候审人义务告知书如何填写? 取保候审权利义务告知书内容 取保候审执行通知书回执 法院向取保候审的人送达开庭的法律文书叫什么?