2009-09-22 12 views
6

私は以下のようなテーブルを持っています。それはまだMySQLの2つの列のタイムスタンプのデフォルトNOW値1067

mysql> SELECT @@sql_mode; 
+------------+ 
| @@sql_mode | 
+------------+ 
|   | 
+------------+ 
1 row in set (0.00 sec) 

を与えている:here私の出力を指摘して私のsql_modeのがNO_ZERO_DATEが含まれていません

CREATE TABLE IF NOT EXISTS mytable (
    id INT NOT NULL AUTO_INCREMENT , 
    create_date TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00' , 
    update_date TIMESTAMP NULL DEFAULT NOW() ON UPDATE NOW() , 
    PRIMARY KEY (`parti_id`)) 
ENGINE = InnoDB; 
hereを示すようになりました1つのデフォルト のMySQLの列制限を回避するために、私は、チップを使用しました

ERROR 1067 (42000) at line xx in file: '/myschema.sql': Invalid default value for 'create_date' 

私はMySQL 5.1.37を使用していますUbuntu

どうすれば修正できますか?ありがとう。

答えて

12

タイムスタンプ列のデフォルト値はCURRENT_TIMESTAMPまたはNOW()です。これはMySQLのよく知られたバグです。

これを解決するには、作成した列のデフォルトに有効なタイムスタンプ値を設定し、CRUDアプリケーションコードにタイムスタンプを挿入します。 更新された列の既定値には、NOW()またはCURRENT_TIMESTAMPを使用します。

基準物質: http://dev.mysql.com/doc/refman/5.1/en/timestamp.html

さらに、この分野でのMySQLの欠点を説明するために、次のコードを考えてみます。

CREATE TABLE testing_timestamps (
    id INT NOT NULL AUTO_INCREMENT, 
    pk_id INT NOT NULL, 
    col1 TIMESTAMP DEFAULT 0, 
    col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY(id) 
); 

delimiter $$ 
CREATE TRIGGER testing_timestamps_trigger 
    AFTER INSERT ON testing_timestamps 
    FOR EACH ROW 
    BEGIN 
    UPDATE testing_timestamps SET col1 = NOW() WHERE id = MAX(id); 
    END; 
$$ 
delimiter ; 

INSERT INTO testing_timestamps (id) VALUES (0); 

この意思表示からの出力:

mysql> INSERT INTO testing_timestamps (id) VALUES (0); 
ERROR 1442 (HY000): Can't update table 'testing_timestamps' in stored function/trigger because it is already used by statement which invoked this stored function/trigger. 

はこれがありますこの事例でトリガーを使用することは良い仕事であるため、バマーです。

+0

の更新を試すことができ、それは機能です: 「テーブル内の1つのTIMESTAMP列の場合、デフォルト値と自動更新値として現在のタイムスタンプを割り当てることができます現在のタイムスタンプをカラムを初期化するためのデフォルト値、自動更新値、またはその両方にすることは可能ですが、現在のタイムスタンプを1つのカラムのデフォルト値にすることはできません。 " –

+0

これが「バグ」かどうかの議論は、これが深刻な迷惑であるために残っています。 2つ目の列を自動更新してnow()のデフォルトで2つのタイムスタンプ列を持たないのはなぜですか?答えは、MySQLはそうしないということです。私は実際にその機能を呼びません。 –

+0

あなたの返事のためにランディーに感謝します。私はあなたが提供したリンクを知っています。私は回避策を探します。しかし、インターネット上に表示されるすべてのトリックは機能しないようです。 –

7

実際、ランディのコードは壊れています。それは突然変異トリガーであるため動作しません。更新を開始したテーブルを更新することはできません。たとえば、SESSIONSテーブルを更新する場合は、UPDATE、INSERT、またはDELETEステートメントを使用してトリガ内のテーブルを変更することはできません。トリガーが接続されているテーブルを変更するには、以下に示すように "NEW"または "OLD"接頭辞を使用するしかありません。 (もちろん、あなたは自由に他のテーブルを更新することができます)。opで説明されている問題を克服する方法の例を次に示します。これを行うと、それが動作していることが

create table sessions (
    id integer not null, 
    created timestamp not null default 0, 
    updated timestamp not null default 0 
); 

delimiter // 
create trigger bifer_sessions_ts before insert on sessions for each row 
begin 
    set new.created = now(); 
    set new.updated = now(); 
end; 
// 
create trigger bufer_sessions_ts before update on sessions for each row 
begin 
    set new.updated = now(); 
end; 
// 
delimiter ; 
1

col1 TIMESTAMP DEFAULT 0, 

col2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 

あなただけの値がクエリでNULLであることを確認し、COL1のためのトリガーを必要としません。答えは認定ガイドに記載されています。

0

デフォルトTIMESTAMPは、同じテーブルのバージョン5.6.1より前のMySQLではサポートされていません。

バージョン5.6以降では、同じテーブル内に2つ以上のTIMESTAMPカラムを使用できます。

あなたがこれはバグではありませんMySQLのバージョン

関連する問題