MySQL日時列のデフォルト値をどのように設定しますか?


898

MySQL日時列のデフォルト値をどのように設定しますか?

SQL Serverではgetdate()です。MySQLに相当するものは何ですか?それが要因である場合、私はMySQL 5.xを使用しています。


4
私のmysqlテーブルで(クエリではなく)CURRENT_TIMESTAMPを使用していますが、これも役立つ場合があります。
ルーベン2012年

15
この機能はMySQL 5.6.5に追加されました。これが誰かを助けることを願っています。optimize-this.blogspot.co.uk/2012/04/...
GhostInTheSecureShell

@GhostInTheSecureShellは、少なくともDebianにそれをインストールするというかなりの使命ですが、間違いなく素晴らしい機能です。最終的には、これらの「2つのCURRENT_TIMESTAMP」に関する質問はすべて軽減されると思います。
Marc DiMillo 2013

now()関数か、列レベルのデフォルト設定で実行できます。
Anshul Sharma

回答:


862

重要な編集:MySQL 5.6.5 以降、これをDATETIMEフィールドで実現できるようになりました。以下の他の投稿をご覧ください...

以前のバージョンでは、DATETIMEでそれを行うことはできません...

しかし、タイムスタンプでそれを行うことができます:

mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
Query OK, 0 rows affected (0.00 sec)

mysql> desc test;
+-------+-------------+------+-----+-------------------+-------+
| Field | Type        | Null | Key | Default           | Extra |
+-------+-------------+------+-----+-------------------+-------+
| str   | varchar(32) | YES  |     | NULL              |       | 
| ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
+-------+-------------+------+-----+-------------------+-------+
2 rows in set (0.00 sec)

mysql> insert into test (str) values ("demo");
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+------+---------------------+
| str  | ts                  |
+------+---------------------+
| demo | 2008-10-03 22:59:52 | 
+------+---------------------+
1 row in set (0.00 sec)

mysql>

**警告:CURRENT_TIMESTAMP ONをデフォルトとして列を定義する場合、常にこの列の値を指定する必要があります。そうしないと、更新時に値が自動的に「now()」にリセットされます。つまり、値を変更したくない場合は、UPDATEステートメントに "[your column name] = [your column name]"(またはその他の値)を含める必要があります。そうしないと、値は "now()"になります。奇妙ですが、本当です。これがお役に立てば幸いです。5.5.56-MariaDBを使用しています**


400
datetimeの範囲は1000〜9999ですが、タイムスタンプの範囲は1970〜2038のみであることに注意することが重要です。これは、システムが生年月日を保存する必要がある場合、または30年の住宅ローンの支払い計画のようなものを処理する必要がある場合に問題になる可能性があります。dev.mysql.com/doc/refman/5.0/en/datetime.html
Kip

13
その自動更新が魔法...次の回答見るようにタイムスタンプを過ぎる気をつけてくださいstackoverflow.com/a/1483959/233906
Cerber

6
バージョン5.6.5から可能です。以下のGustavの回答を参照してください(MySQLがまだ5.0だったときに回答が投稿されたことわかります!)
e2-e4

4
@Kip、こんにちは、DATE列のデフォルト値を設定することは可能ですか?(datetime列ではありません)。
Sajib Acharya 2016

tiは、DATE列では使用できないようです
。DATETIME

599

バージョン5.6.5では、日時列にデフォルト値を設定し、行が更新されたときに更新される列を作成することもできます。タイプ定義:

CREATE TABLE foo (
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
)

リファレンス:http : //optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html


3
'menu_creation_time'の無効なデフォルト値
Fernando Trindade

2
@FernandoTrindade MySQLバージョン5.6.5以降が必要です。sqlfiddle.com/#!9/dd2be
Gustav Bertram

1
@GustavBertram、バージョン5.6.22を使用していますが、それでも次のようなエラーが発生しました。エラーコード:1294。'UpdateDate '列の無効なON UPDATE句
Manish Sapkal

@ManishSapkal DATETIMEではなくTIMESTAMPを使用しています。また、NULLにしないでください。
グスタフベルトラム2014

1
「ON UPDATE」構文は間違っていると思います。dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.htmlによると、それは正しいはずですdt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Dan Bough

148

MySQL(バージョン5.6.5より前)では、デフォルトのDateTime値に関数を使用できません。TIMESTAMPは奇妙な動作をするため適切ではなく、入力データとしての使用は推奨されません。(MySQLデータタイプのデフォルトを参照してください。)

つまり、トリガーを作成することでこれを実現できます。

DateTime型のDateCreatedフィールドを持つテーブルがあります。そのテーブルに「挿入前」と「SET NEW.DateCreated=NOW()」のトリガーを作成しました。

これが誰かの役に立つことを願っています。


21
CREATE TRIGGER trigger_foo_SetCreatedAt BEFORE INSERT ON foo ON EACH ROW SET NEW.created_at = UTC_TIMESTAMP();
kgriffs

5
おそらく、将来の健全性(メンテナンス)のトリガーよりもタイムスタンプを使用する方が良いでしょう。これは解決策ではありますが、トリガーのユースケースとしては簡単です。
getWeberForStackExchange 2010年

8
おそらくデフォルト値のみを設定したいと思うでしょうIF NEW.created_at IS NOT NULL
Petr Peller

132

私にとってはトリガーアプローチが最も効果的でしたが、そのアプローチには問題が見つかりました。挿入時に日付フィールドを現在時刻に設定するための基本的なトリガーを検討してください。

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = NOW();

これは通常は素晴らしいですが、次のようにINSERTステートメントを使用してフィールドを手動で設定したいとします。

INSERT INTO tblMyTable(name, dateAdded) VALUES('Alice', '2010-01-03 04:30:43');

何が起こるかというと、トリガーはフィールドに指定された値をすぐに上書きするため、現在以外の時刻を設定する唯一の方法は、フォローアップUPDATEステートメントです-残念です!値が指定されているときにこの動作をオーバーライドするには、IFNULL演算子を使用して、わずかに変更された次のトリガーを試してください。

CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
    FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());

これにより、両方の世界で最良の結果が得られます。日付列に値を指定すると、それが使用されます。それ以外の場合は、デフォルトで現在の時刻が使用されます。それでも、テーブル定義のDEFAULT GETDATE()のようなクリーンなものに比べてゲットーですが、近づいています!


5
挿入時の明示的なユーザー値の上書きに関する警告を確認するための+1。
キップ

2
個人的にはこれが最善の方法だと思います。TIMESTAMPは確かに奇妙な振る舞いをしており、2038年の制限のあるコードは決して記述しません。
Eric

気にしないで、私はそれを考え出した。許可するフィールドを設定するのを忘れましたNULL。警告はもうありません。
Kaji

トリガーは悪です!何かをする他の方法がないときにのみ、それらを使用します。トリガーを使用するよりも、5.6.x idにアップグレードした方が良いです。
ksymeon 2015年

4
MySQL 5.5では、IFNULLはDATETIMEでは機能しません。上記のトリガーを使用すると、dateAdded「0000-00-00 00:00:00」がすべて表示されます。これを使用するとうまくいきます: `FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW(); 終了IF; `
ケニー

28

2つの日時フィールドを持つテーブルでこの変更ステートメントを使用して、これを解決することができました。

ALTER TABLE `test_table`
  CHANGE COLUMN `created_dt` `created_dt` TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
  CHANGE COLUMN `updated_dt` `updated_dt` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

これは、now()関数が機能することを期待したとおりに機能します。nullを挿入するか、created_dtおよびupdated_dtフィールドを無視すると、両方のフィールドで完全なタイムスタンプ値が得られます。行を更新すると、updated_dtが変更されます。MySQLクエリブラウザーを介してレコードを挿入する場合、もう1つのステップ、新しいタイムスタンプでcreated_dtを処理するトリガーが必要です。

CREATE TRIGGER trig_test_table_insert BEFORE INSERT ON `test_table`
    FOR EACH ROW SET NEW.created_dt = NOW();

トリガーには、命名規則[trig] _ [my_table_name] _ [insert]を好きなように設定できます


つまり、MySQLクエリブラウザを介して、グリッドを介してinsert()ステートメントなしで手動でレコードを挿入する場合、トリガーが必要です。常に挿入ステートメントを使用する場合、トリガーは完全に不要です。

おっと!つまり、トリガー名は機能にまったく影響しないため、トリガー(名前)は任意の名前にすることができます。...ほとんどの人はそれを知っているだろうが、MySQLへの新しいいくつかの人々は知らないかもしれない

改行、改行がないことを残念に思います。セミコロンを使用して、各行の終わりを示します。

24

トリガーを使用してこの種のことを行うことができます。

CREATE TABLE `MyTable` (
`MyTable_ID`  int UNSIGNED NOT NULL AUTO_INCREMENT ,
`MyData`  varchar(10) NOT NULL ,
`CreationDate`  datetime NULL ,
`UpdateDate`  datetime NULL ,
PRIMARY KEY (`MyTable_ID`)
)
;

CREATE TRIGGER `MyTable_INSERT` BEFORE INSERT ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the creation date
    SET new.CreationDate = now();

        -- Set the udpate date
    Set new.UpdateDate = now();
END;

CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END;

18

MySQLでデフォルトのDATETIME値を設定しようと心を失ったすべての人にとって、私はあなたがどのように感じ/感じたかを正確に知っています。だからここにあります:

ALTER TABLE  `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0

0の前後に一重引用符/二重引用符を追加していないこと注意してください

これを解決した後、私は文字通りジャンプしています:D


8
現在時刻ではなく挿入しません。'0000-00-00 00:00:00'が挿入されます。
ピットディガー2011

8
現在の時刻を設定するとは言いませんでした。多くのPPLがデフォルトのゼロ値を設定しようとしましたが、機能しません。引用符を削除する必要があります。この発見は多くの時間とフラストレーションを引き起こしたので、私はそれをコミュニティーと共有することを考えました。あなたのような人々は、他の人々と有用な情報を共有することに興味を失っているユーザーに対して責任があります。私は-1を取得する理由を真剣に見ていません!なんでも。
Augiwan

3
同じことがDATETIME NOT NULLでも実現できます。
ブレンダンバード2014

例のsqlコマンド内にはもう1つの `文字があります。これは1文字の編集のみなので、編集できません。
quapka 2016年

あなたのコードは私にとってALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
Smith


14

すでにテーブルを作成している場合は、使用できます

デフォルト値を現在の日時に変更するには

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

デフォルト値を「2015-05-11 13:01:01」に変更するには

ALTER TABLE <TABLE_NAME> 
CHANGE COLUMN <COLUMN_NAME> <COLUMN_NAME> DATETIME NOT NULL DEFAULT '2015-05-11 13:01:01';


9

MySql Server 5.7.11を実行していて、次の文を実行します。

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '0000-00-00 00:00:00'

機能していません。しかし、以下:

ALTER TABLE table_name CHANGE date_column datetime NOT NULL DEFAULT '1000-01-01 00:00:00'

ただ働くます。

傍注として、それはmysqlのドキュメントで言及されています:

DATEタイプは、日付部分はあるが時間部分はない値に使用されます。MySQLはDATE値を取得して 'YYYY-MM-DD'形式で表示します。サポートされる範囲は「1000-01-01」から「9999-12-31」です。

彼らがまた言っても:

無効なDATE、DATETIME、またはTIMESTAMPの値は、適切なタイプ(「0000-00-00」または「0000-00-00 00:00:00」)の「ゼロ」値に変換されます。


8

now()を使用して日時列の値を設定できますが、それをデフォルト値として使用できないことに注意してください。


4
本当。今すぐ使用してみたところ、「エラーコード:1067。デフォルト値が無効です。」というエラーが発生しました。だから答えは何ですか?;-)
Brian Boatright、

これは、MySQLバージョン5.5および5.6を危険にさらすための最良のソリューションです。バージョン5.5の場合、値を事前に決定し、NOW()後で挿入に使用します。バージョン5.6の場合は、単にNOW()デフォルト値として設定します。
Abel Callejo 2017

8

解決策としてTIMESTAMP列を使用するすべての人のために、マニュアルから次の制限を2番目にしたいと思います:

http://dev.mysql.com/doc/refman/5.0/en/datetime.html

「TIMESTAMPデータ型の範囲は、 ' 1970-01-01 00:00:01' UTCから ' 2038-01-19 03:14:07です。 ' UTCです。MySQLバージョンとSQLに応じて、さまざまなプロパティがあります。サーバーが実行されているモード。これらのプロパティについては、このセクションで後述します。

したがって、これは明らかに約28年後にソフトウェアを破壊します。

データベース側での唯一の解決策は、他の回答で述べられているようなトリガーを使用することだと思います。


2
MySQLが20年後に更新され、その制限が削除された場合はどうなりますか?それが可能かどうかはわかりませんが、考えただけです。
NessDan、2012年

7

複数行トリガーを定義している間、MySQLコンパイラーがセミコロンをトリガーの終わりとして受け取り、エラーを生成するため、区切り文字を変更する必要があります。例えば

DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
        -- Set the udpate date
    Set new.UpdateDate = now();
END//
DELIMITER ;

5

MySQL 5.1でこれを行う方法は次のとおりです。

ALTER TABLE `table_name` CHANGE `column_name` `column_name` 
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

列名を2回入力する必要がある理由がわかりません。


5
CHANGEは、フィールドの名前を変更するためにも使用されます。最初の列名は「古い」、2番目の列名は「新しい」です。フィールドの名前を変更しない場合は冗長に見えます。美的に不快すぎる場合は、MODIFYを試してください。
ジョンゴードン

5

DATETIMEデフォルトの定義ではこれを行うことはできませんが、次のように、selectステートメントをinsertステートメントに組み込むだけです。

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))

表を引用符で囲んでいないことに注意してください。

MySQL 5.5の場合


3

デフォルト値をNOW()に設定しようとしている場合、MySQLはそれをサポートしていないと思います。MySQLでは、デフォルトとしてCURRENT_TIMESTAMPを指定できるTIMESTAMPデータ型の列を除いて、関数または式をどのタイプの列のデフォルト値としても使用できません。


3

mysqlは現在の時間(その挿入の時間)を提供するnow()を呼び出す組み込み関数がmysqlであるため、mysqlでは単純だと思います。

したがって、クエリは次のようになります。

CREATE TABLE defaultforTime(
    `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
    `modification_time` DATETIME default now()
);

ありがとうございました。


2
CREATE TABLE `testtable` (
    `id` INT(10) NULL DEFAULT NULL,
    `colname` DATETIME NULL DEFAULT '1999-12-12 12:12:12'
)

上記のクエリで「testtable」を作成するために、DATETIME列のデフォルト値として「1999-12-12 12:12:12」を使用しました colname


1

次のコードを使用します

DELIMITER $$

    CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
    BEGIN
      SET new.datefield = NOW();
    END $$

    DELIMITER ;

0

デフォルト値をNOW()として設定しようとしている場合、MySQLは、そのカラムのタイプをDATETIMEではなくTIMESTAMPに変更する必要があることをサポートしています。TIMESTAMPにはデフォルトとして現在の日付と時刻があります。問題が解決されると思います。


0

たとえば、create_at列とupdate_at列があり、両方ともDATETIMEであり、現在のデフォルト値が必要な「site」という名前のテーブルがある場合、次のSQLを実行してこれを実現できます。

ALTER TABLE `site` CHANGE` created_at` `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE` created_at` `created_at` DATETIME NULL DEFAULT NULL;

ALTER TABLE `site` CHANGE` updated_at` `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABLE `site` CHANGE` updated_at` `updated_at` DATETIME NULL DEFAULT NULL;

テーブルには、デフォルト値がCUREENT TIMESTAMPのタイプTIMESTAMPの2つの列を含めることができないため、ステートメントのシーケンスは重要です。


0

これは私のトリガーの例です:

/************ ROLE ************/
drop table if exists `role`;
create table `role` (
    `id_role` bigint(20) unsigned not null auto_increment,
    `date_created` datetime,
    `date_deleted` datetime,
    `name` varchar(35) not null,
    `description` text,
    primary key (`id_role`)
) comment='';

drop trigger if exists `role_date_created`;
create trigger `role_date_created` before insert
    on `role`
    for each row 
    set new.`date_created` = now();


0

MySQL 8.xで正常に動作する

CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `dateCreated` datetime DEFAULT CURRENT_TIMESTAMP,
      `dateUpdated` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      UNIQUE KEY `mobile_UNIQUE` (`mobile`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-3

デフォルトのタイムスタンプを解決できます。まず、使用している文字セットを検討してください。たとえば、utf8を使用した場合、この文字セットはすべての言語をサポートし、laten1を使用した場合、この文字セットは英語のみをサポートします。次のsetp任意のプロジェクトで作業している場合は、クライアントのタイムゾーンを把握し、自分がクライアントゾーンであることを選択する必要があります。このステップは必須です。


2
DateTime列にデフォルト値を含めることはできません。「機能」が文書化されています。すべての開発者が文字エンコーディングを変更するためのアクセス権を持っているわけではありません。また、サーバーをそのクライアントのタイムゾーンに設定することは、通常、特にクライアントがすべて単一のタイムゾーン領域にネイティブではない場合は不可能です。
rlb.usa
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.