日向夏特殊応援部隊

俺様向けメモ

SQL だけで動的に ADD PARTITION する

DEALLOCATE PREPARE し忘れていたので修正しました。id:tokuhirom++

結論から言えば プリペアド ステートメントの為の SQL 構文 を使えば出来る。

CREATE TABLE `timeline` (
  `id` int(10) unsigned NOT NULL,
  `guid` int(10) unsigned NOT NULL,
  `title` varchar(140) DEFAULT NULL,
  `created_on` datetime NOT NULL,
  PRIMARY KEY (`id`,`created_on`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE (TO_DAYS(created_on))
(PARTITION p20101110 VALUES LESS THAN (734452))
ENGINE = InnoDB;

DROP PROCEDURE add_partition;
DELIMITER //
CREATE PROCEDURE add_partition(IN a_table TEXT, IN a_date DATE)
  BEGIN
    SELECT CONCAT(
      'ALTER TABLE timeline ADD PARTITION ( PARTITION ', 
      DATE_FORMAT(a_date, 'p%Y%m%d'), 
      ' VALUES LESS THAN(', TO_DAYS(a_date + INTERVAL 1 DAY), ') )') INTO @ddl;
    PREPARE ddl_stmt FROM @ddl;
    EXECUTE ddl_stmt;
    DEALLOCATE PREPARE ddl_stmt;
  END;
//
DELIMITER ;

CALL add_partition('timeline', '2010-11-11');

みたいな感じ。PREPARE の FROM 句は文字列リテラルかユーザー変数*1しか使えないのでプロシージャのローカル変数*2は使えないので注意。

PREPARE 構文を使うと SQL で生成した SQL 文が使えるようになるのが中々面白い。

*1:@なんちゃらって奴

*2:DECLARE して局所化した変数