鉴于此:
delimiter //
create procedure setup()
begin
declare d datetime;
set d = rounddate(now());
create table s_time (req_id int not null,
ser_id int not null,
hel_id int not null,
posted int unsigned not null,
completed int unsigned not null default 0
)
partition by range (completed) (partition p0 values less than ( unix_timestamp(d) ),
partition p1 values less than ( unix_timestamp(d + interval 1 day) )
);
end//
我明白了:
ERROR 1064 (42000) : Constant, random, or timezone-dependent expression in (sub)partitioning function are not allowed
有没有办法让它工作,或者我必须使用硬编码字符串输入。即使用:unix_timestamp('2012-07-07 00:00:00')
答案 0 :(得分:6)
为了使解决方案保持完整sql,这就是我所发现的。
delimiter //
create procedure setup()
begin
declare d, d2 int;
set d = unix_timestamp();
set d2 = unix_timestamp(now() + interval 1 day);
create table s_time (req_id int not null,
ser_id int not null,
hel_id int not null,
posted int unsigned not null,
completed int unsigned not null default 0
);
SET @stmt = concat('alter table s_time PARTITION BY RANGE (completed) (
partition p0 values less than (', d, '),
partition p1 values less than (', d2, '))');
PREPARE pStmt FROM @stmt;
EXECUTE pStmt;
DEALLOCATE PREPARE pStmt;
end//
delimiter ;
call setup();
答案 1 :(得分:3)
这不起作用的原因不太明确,我怀疑文档或错误消息中存在错误。在我看来,您收到的错误是不恰当的。
分区中不允许使用以下结构 表达式:
- 存储过程,存储函数,UDF或插件。
- 声明变量或用户变量。
这解释了您的表定义失败的原因。
现在,如何摆脱你的变量?如果您尝试从分区定义中删除声明的变量:
CREATE TABLE s_time (
completed INT UNSIGNED NOT NULL DEFAULT 0
)
PARTITION BY RANGE ( completed ) (
PARTITION p0 VALUES LESS THAN ( UNIX_TIMESTAMP() )
);
你会得到同样的错误。但是,MySQL manual州:
也可以在VALUES LESS THAN子句中使用表达式。 但是,MySQL必须能够评估表达式的返回值 作为LESS THAN(<)比较的一部分。
根据此定义,UNIX_TIMESTAMP()
应该是有效的表达式。手册中的这句话至少可以说是不准确的。我很好奇,看看其他人是否可以提供另一种理解。
现在,查看错误消息,如果您将LESS THAN
子句视为“分区函数”的一部分,则错误消息开始有意义:
错误1064(42000):常量,随机或与时区相关的表达式 (sub)分区函数或不允许使用LESS THAN子句
“随机”,它们也意味着非确定性,UNIX_TIMESTAMP()
函数根据定义。
为了实现您的目标,我没有看到其他解决方案,只是使用外部脚本生成合适的ALTER TABLE
命令。
1)创建初始表:
CREATE TABLE s_time (
req_id INT NOT NULL,
ser_id INT NOT NULL,
hel_id INT NOT NULL,
posted INT UNSIGNED NOT NULL,
completed INT UNSIGNED NOT NULL DEFAULT 0
) PARTITION BY RANGE (completed) (
PARTITION p0 VALUES LESS THAN (0),
PARTITION p1 VALUES LESS THAN (1)
);
2)Reorganise the partitions时不时(例如使用PHP):
<?php
$query =
"ALTER TABLE s_time REORGANIZE PARTITION p0, p1 INTO (
PARTITION p0 VALUES LESS THAN ($today),
PARTITION p1 VALUES LESS THAN ($tomorrow)
)";