使用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函数中拆分字符串。