5

これを考えると:

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')

4

2 に答える 2

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();
于 2012-06-26T13:56:51.453 に答える
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のマニュアルには次のように記載されています。

VALUESLESSTHAN句で式を使用することもできます。ただし、MySQLは、LESS THAN(<)比較の一部として式の戻り値を評価できる必要があります。

この定義によれば、UNIX_TIMESTAMP()は有効な式である必要があります。マニュアルからのこの文は控えめに言っても不正確です。他の誰かが別の理解を提供できるかどうかを知りたいと思います。

ここで、エラーメッセージを見て、LESS THAN句を「パーティショニング関数」の一部と見なすと、エラーメッセージは意味をなし始めます。

エラー1064(42000):(サブ)パーティション化関数またはLESSTHAN句での定数、ランダム、またはタイムゾーンに依存する式は許可されていません

「ランダム」とは、非決定論的であることも意味します。これは、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)時々パーティションを再編成します(たとえばPHPを使用):

<?php
    $query = 
        "ALTER TABLE s_time REORGANIZE PARTITION p0, p1 INTO (
            PARTITION p0 VALUES LESS THAN ($today),
            PARTITION p1 VALUES LESS THAN ($tomorrow)
        )";

ここで概念実証を参照してください。

于 2012-06-25T20:00:55.230 に答える