使用MySQL中的存储过程创建明年的日历表

问题描述

我需要使用MySQL中的存储过程来创建明年的日历表。

在此代码上,问题在于设置下一年的值,因为结果是

Procedure executed successfully
Affected rows: 0

我明年无法设置这部分代码

'@tbl-01-01'+间隔d.i * 1000 + c.i * 100 + a.i * 10 + b.i DAY AS date

如何在此过程中设置下一年的变量?

有什么主意吗?

BEGIN

-- create a 2021 year
SET @tbl = DATE_FORMAT(DATE_ADD(CURDATE(),INTERVAL 1 YEAR),'%Y');

-- create a calendar table 2021
SET @s = CONCAT('DROP TABLE IF EXISTS tbl_calendar_',@tbl);
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

SET @s = CONCAT('CREATE TABLE IF NOT EXISTS tbl_calendar_',@tbl,' LIKE tbl_calendar_2020');
PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

-- create a ints table
DROP TABLE
IF EXISTS ints;

CREATE TABLE ints (i INTEGER);

INSERT INTO ints VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

-- insert into calendar table 2021 from interval day
SET @s = CONCAT('INSERT INTO tbl_calendar_',' SELECT
    cal.date AS cdate,DAY (cal.date) AS cday,MONTH (cal.date) AS cmonth,YEAR (cal.date) AS cyear,NULL
FROM
    (
        SELECT
            \'`@tbl`-01-01\' + INTERVAL d.i * 1000 + c.i * 100 + a.i * 10 + b.i DAY AS date
        FROM
            ints a
        JOIN ints b
        JOIN ints c
        JOIN ints d
        ORDER BY
            d.i * 1000 + c.i * 100 + a.i * 10 + b.i
    ) cal
WHERE
    cal.date BETWEEN \'`@tbl`-01-01\'
AND \'`@tbl`-12-31\'
ORDER BY
    cal.date ASC;');  

PREPARE stmt FROM @s;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

END

解决方法

您可以在concat函数中拆分字符串,并像在insert子句中那样将变量置于字符串之外。看起来像这样:

SET @s = CONCAT('INSERT INTO tbl_calendar_',@tbl,' SELECT
    cal.date AS cdate,DAY (cal.date) AS cday,MONTH (cal.date) AS cmonth,YEAR (cal.date) AS cyear,NULL
FROM
    (
        SELECT \'','-01-01\' + INTERVAL d.i * 1000 + c.i * 100 + a.i * 10 + b.i DAY AS date
         ...'

每次在查询中使用@tbl变量时,都需要像这样在concat函数中拆分字符串。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...