【问题标题】:MYSQL stored procedure create dynamic table from dateMYSQL存储过程从日期创建动态表
【发布时间】:2017-02-14 09:42:26
【问题描述】:

我在动态创建表名时遇到了一点问题。

例如, 此查询(SELECT DATE_FORMAT(NOW(),'%Y%m')) 返回201702

我的动机是检查表是否存在。 如果它不存在,它将自动创建它。 现在这是我的问题。

messages_`,datereturn

看来我什至编译都会出错。我们如何传递参数来创建表?

非常感谢您的帮助。

完整代码:

   BEGIN
    SET datereturn = (SELECT DATE_FORMAT(NOW(),'%Y%m'));

    CREATE TABLE IF NOT EXISTS `messages_`,datereturn (
      `mid` bigint(17) NOT NULL,
      `uid` int(11) NOT NULL,
      `csid` int(11) NOT NULL,
      `content` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
      `content_type` tinyint(4) NOT NULL,
      `datecreated` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `datecreated1` bigint(13) DEFAULT NULL,
      PRIMARY KEY (`mid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    END

编辑:它与建议的答案不同。 我正在使用 MySQL 5.6 使表动态化。 上面建议的线程不适用于我的版本。 所以,我不知道为什么它可能是重复的。

【问题讨论】:

  • 你的意思是CONCAT("messages_", datereturn)
  • @PM77-1,好吧,我试过了,我得到了这个错误You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' datereturn) ( `mid` bigint(17) NOT NULL, `uid` int(11) NOT NULL, `csid' at line 4

标签: mysql stored-procedures


【解决方案1】:

存储过程不允许您将变量组合成 SQL 标识符。换句话说,必须在解析查询之前设置表名等内容。

所以你需要创建一个dynamic SQL statement 并让存储过程在运行时准备CREATE TABLE 语句:

BEGIN
    SET @sql = CONCAT('CREATE TABLE IF NOT EXISTS messages_',datereturn,' (',
      'mid bigint NOT NULL, ',
      'uid int NOT NULL, ',
      'csid int NOT NULL, ',
      'content varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, ',
      'content_type tinyint NOT NULL, ',
      'datecreated timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, ',
      'datecreated1 bigint DEFAULT NULL, ',
      'PRIMARY KEY (mid)',
    ') ENGINE=InnoDB DEFAULT CHARSET=latin1');

    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;    
END

(注意:我没有测试过这段代码,所以如果我错过了一个报价,我希望你知道如何解决这个问题。)

在此示例中,我还删除了您的反引号,因为它们不是必需的,并且我删除了 int 类型的长度选项,因为它们没有效果。

说了这么多,我不得不质疑为什么您每次约会都需要一张桌子。对我来说似乎是一种代码气味。你有考虑过creating a table partitioned by date吗?

【讨论】:

  • 比尔,你是救命恩人。我需要将此参数返回给服务器。所以插入方法将基于日期。好吧,这是我第一次听到按日期分区的表。我正在调查。
【解决方案2】:
SET @CrtTbl = CONCAT('CREATE TABLE', CONCAT('`messages_', datererun), '(mid bigint(17) NOT NULL, .... and so on

...

PREPARE CrtTblStmt FROM @CrtTbl;
EXECUTE CrtTblStmt;
DEALLOCATE PREPARE CrtTblStmt;

类似的东西

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-18
    • 2016-10-05
    • 2013-07-18
    • 2014-08-13
    • 2016-11-11
    • 2017-10-14
    • 2021-07-10
    相关资源
    最近更新 更多