问题描述
我需要使用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函数中拆分字符串。