首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 預存程序中動態建表:表名作為參數傳入的最佳實踐

     編輯:MySQL 資料庫相關知識

場景

需按日期動態建立分區表(如 mail_rare_visit_20170111),表名在運行期確定,必須用動態 SQL。

完整範例

BEGIN
  DECLARE date_str      VARCHAR(8);
  DECLARE table_prefix  VARCHAR(20) DEFAULT 'mail_rare_visit_';
  DECLARE tbl_name      VARCHAR(64);
  DECLARE ddl_sql       TEXT;

  SET date_str = DATE_FORMAT(CURRENT_DATE(), '%Y%m%d');
  SET tbl_name = CONCAT(table_prefix, date_str);

  SET ddl_sql = CONCAT('CREATE TABLE ', tbl_name, '(
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `user_id` INT(11) NOT NULL,
    `city_id` INT(11) NOT NULL,
    `email` VARCHAR(300) NOT NULL,
    `channel_id` INT(11) DEFAULT NULL,
    `w_revenue` DECIMAL(7,6) NOT NULL DEFAULT 0.000000,
    `w_buy` DECIMAL(7,6) NOT NULL DEFAULT 0.000000,
    `w_browse` DECIMAL(7,6) NOT NULL DEFAULT 0.000000,
    `rec_goods` VARCHAR(800) DEFAULT NULL,
    `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `idx_user_id` (`user_id`),
    KEY `idx_city_id` (`city_id`),
    KEY `idx_email` (`email`),
    KEY `idx_channel_id` (`channel_id`)
  ) ENGINE=MyISAM DEFAULT CHARSET=utf8;');

  PREPARE stmt FROM ddl_sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END;

關鍵點

  1. 表名/庫名/欄名等識別符無法用預處理佔位符,只能拼接字串後 PREPARE。
  2. 用戶變數 @tbl_name 或局部變數均可,拼接時注意防注入(此處為內部邏輯生成,風險可控)。
  3. PREPARE/EXECUTE/DEALLOCATE 三步不可漏,避免洩漏 prepared statement 句柄。
  4. 動態 DDL 同樣適用 ALTER TABLE、DROP TABLE 等場景。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved