792

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

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


  • 私は私のmysqlテーブルでCURRENT_TIMESTAMPを使用しています(クエリではありません)、多分これも役に立ちます。 - Ruben
  • この機能はMySQL 5.6.5に追加されました。これが誰かに役立つことを願っています。optimize-this.blogspot.co.uk/2012/04/… - GhostInTheSecureShell
  • @GhostInTheSecureShellは少なくともDebianにインストールするという非常に重要な使命ですが、間違いなく素晴らしい機能です。結局、これら2つの「2つのCURRENT_TIMESTAMP」がすべてだと思います。質問は軽減されます! - Marc DiMillo

24 답변


778

重要な編集:これはDATETIMEフィールドでこれを達成することが今では可能です。MySQL 5.6.5を見てください。他の記事以下...

以前のバージョンではDATETIMEではそれができません...

しかし、あなたはTIMESTAMPでそれをすることができます:

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を使用しています**


  • datetimeの範囲は1000〜9999ですが、注意が必要です。タイムスタンプの範囲は1970-2038だけです。あなたのシステムが誕生日を保存しなければならないならば、これは問題になるかもしれません、または、あなたは30年の住宅ローンのための支払い計画のような何かを扱わなければなりません。dev.mysql.com/doc/refman/5.0/en/datetime.html - Kip
  • タイムスタンプは魔法のように自動更新されるので注意してください。次の答えを見てください。stackoverflow.com/a/1483959/233906 - Cerber
  • それですバージョン5.6.5から可能になりました、下記のGustavの答えを見てください(あなたの答えはMySQLがまだ5.0の時に投稿されたと思います!) - Ring Ø
  • @ Kipさん、こんにちは。DATEカラム? (ないdatetimeカラム)。 - Sajib Acharya
  • DATE列には使用できないようです:DATETIMEデータ型を使用する必要があります - Fabio Napodano

514

バージョン5.6.5では、datetimeカラムにデフォルト値を設定することができ、さらに行が更新されたときに更新されるカラムを作成することさえ可能です。型の定義

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


  • ' menu_creation_time'の無効なデフォルト値です - Fernando Trindade
  • @FernandoTrindade MySQLバージョン5.6.5以降が必要です。あなたはそれがここで働いているのを見ることができます:sqlfiddle.com/#!9/dd2be - Gustav Bertram
  • @GustavBertram、私はバージョン5.6.22を使用しています、しかし、それでも私は以下の通りエラーを得ました:CREATE TABLE tbl(挿入日付日付NULLデフォルトCURRENT_TIMESTAMP、更新日付TIMESTAMP NULL更新CURRENT_TIMESTAMP(6))。エラーコード:1294。' UpdateDate&#39の無効なON UPDATE句です。カラム - Manish Sapkal
  • @ManishSapkal DATETIMEではなくTIMESTAMPを使用しています。また、NULLにしないでください。 - Gustav Bertram
  • ちょっと注意 - これはうまくいきませんdate - Nick

139

MySQL(バージョン5.6.5より前)では、デフォルトのDateTime値に関数を使用することはできません。 TIMESTAMPはその奇妙な振る舞いのために適しておらず、入力データとしての使用にはお勧めできません。 (見るMySQLデータ型のデフォルト。)

それは言った、あなたはこれを達成することができますトリガーを作成することによって

DateTime型のDateCreatedフィールドを持つテーブルがあります。そのテーブルに "Before Insert"と ""のトリガを作成しました。SET NEW.DateCreated=NOW()「そしてそれは素晴らしい仕事だ。

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


  • CREATE TRIGGER trigger_foo_SetCreatedAt各行設定のためにfooを挿入する前にNEW.created_at = UTC_TIMESTAMP(); - kgriffs
  • 将来の健全性(メンテナンス)をトリガーするよりも、おそらくタイムスタンプを使用したほうがよいでしょう。これは解決策ですが、これはトリガーのごく簡単な使用例です。 - getWeberForStackExchange
  • おそらくデフォルト値だけを設定したいでしょうIF NEW.created_at IS NOT NULL - Petr Peller

129

私にとっては、トリガーアプローチが最も効果的でしたが、そのアプローチには問題がありました。挿入時に日付フィールドを現在時刻に設定する基本的なトリガーを考えてみます。

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()のようなクリーンなものに相対的なゲットーです、しかし我々は近づいています!


  • 挿入時に明示的なユーザー値を上書きして警告を承認する場合は+1。 - Kip
  • 私は個人的にこれが最善の方法だと思います。 TIMESTAMPは確かに奇妙な振る舞いをしており、私は2038年の制限を持つコードを書くことは決してないでしょう。 - Eric
  • 気にしないで、私はそれを考え出した。許可するフィールドを設定するのを忘れたNULL。もう警告はありません。 - Kaji
  • トリガーは悪です!他に何かをする方法がない場合にのみ、それらを使用してください。トリガーを使用するよりも、5.6.x idにアップグレードしたほうがよいでしょう。 - ksymeon
  • MySQL 5.5では、IFNULLはDATETIMEで機能しません。上記のトリガーを使用してdateAddedすべての' 0000-00-00 00:00:00'が表示されます。これを使用してトリックを行います。 `FOR EACH ROW IF NEW.dateAdded = 0 THEN SET NEW.dateAdded = NOW(); END IF; ` - Kenney

23

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

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]が好きなものなら何でも構いません。


  • 私は言いたいのですが、insert()ステートメントを使わずにMySQLのクエリブラウザを介して手動でレコードを挿入する場合、トリガが必要です。あなたが常にinsert文を使うのであれば、トリガは全く不要です。 - user188217
  • おっと!つまり、トリガー名は機能にまったく影響しないため、トリガー(名前)は好きな名前にすることができます。ほとんどの人はそれを知っているでしょう、しかしMySQLに不慣れな何人かの人々は知らないかもしれません... - user188217
  • はい、改行がないのが残念。セミコロンを使用して各行の終わりを示します。 - user188217
  • これはMysql 5.5の回避策として機能します。ありがとう - Aakash

22

あなたはこの種のことをするためにトリガを使うことができます。

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;


15

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

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

それを注意深く観察する一重引用符/二重引用符を追加していませんの周辺

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


  • 現在時刻ではない挿入はありません。 ' 0000-00-00 00:00:00'が挿入されます。 - Pit Digger
  • 現在時刻を設定するとは言いませんでした。多くのpplはデフォルトのゼロ値を設定しようとしていましたが、うまくいきませんでした。引用符を削除する必要があります。この発見は多くの時間とフラストレーションを引き起こしたので、私はそれをコミュニティと共有することを考えました。あなたのような人々は、有用な情報を他の人々と共有することに興味を失うユーザに対して責任があります。私は真剣に-1を得る理由を見てはいけない!なんでも。 - Augiwan
  • DATETIME NOT NULLでも同じことが達成できます。 - Brendan Byrd
  • sqlコマンドの例の中にはもう1つの `文字がありますが、これは1文字の編集のみなので編集できません。 - quapka

13

MySQL 5.6はこの問題を修正しました

ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'


12

これは本当にひどいニュースです。これは、これに対する長い間保留中のバグ/機能要求です。。その議論はまたタイムスタンプデータ型の制限について話します。

私はこのことを実行することの問題は何であるかを真剣に思っています。



8

あなたがすでにテーブルを作成しているなら、あなたは使うことができます

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

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


7

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年であなたのソフトウェアを壊すでしょう。

データベース側での唯一の解決策は他の答えで述べたようなトリガーを使うことであると私は信じています。


  • MySQLが今から20年後に更新され、その制限が取り除かれた場合はどうなりますか?それが可能かどうかはわかりませんが、考えているだけです。 - NessDan

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 ;


6

datetime列の値を設定するためにnow()を使用することができますが、それをデフォルト値として使用することはできません。


  • 本当です。今すぐ使用しようとしたところ、「エラーコード:1067。無効なデフォルト値」というエラーが表示されました。だから答えは何ですか? ;-) - Brian Boatright
  • これはMySQLバージョン5.5と5.6を妥協するための最善の解決策です。バージョン5.5の場合は、NOW()後で挿入に使用します。バージョン5.6では、単に設定するNOW()デフォルト値として。 - Abel Callejo

6

私はMySqlサーバー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は 'YYYY-MM-DD'形式でDATE値を取得して表示します。サポートされている範囲は '1000-01-01'から '9999-12-31'です。

彼らが言っても:

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


5

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

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

テーブルの周りに引用符がないことに注意してください。

MySQL 5.5の場合


  • (select now())ではなくnow()で十分です - dimus

4

これはMySQL 5.1でそれをする方法です:

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

列名を2回入力しなければならない理由はわかりません。


  • CHANGEはフィールドの名前を変更するためのものです。最初の列名は&#39;古い&#39;、2番目の列名は&#39;新しい&#39;です。フィールドの名前を変更していない場合は、冗長に見えます。審美的に不快すぎる場合は、MODIFYを試してください。 - John Gordon

3

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


2

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

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


2

次のコードを使う

DELIMITER $$

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

    DELIMITER ;


2

mysqlではnow()と呼ばれる組み込み関数が現在の時刻(その挿入時刻)を与えるので、mysqlでは単純だと思います。

だからあなたのクエリは同様に見えるはずです

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

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


0

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


0

たとえば、DATETIMEで、現在のデフォルト値が必要なcreated_at列とupdate_at列を含む '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();


-2

デフォルトのタイムスタンプを解決できます。たとえば、この文字セットがすべての言語をサポートしている場合や、この文字セットが英語のみをサポートしている場合は、どの文字セットを使用しているかを検討してください。あなたが何らかのプロジェクトの下で働いているなら次の設定はあなたがクライアントタイムゾーンを知っていて、あなたがクライアントゾーンであることを選択するべきです。このステップは必須です。


  • DateTime列にはデフォルト値を指定できません。これは文書化された機能です。すべての開発者が自分の文字エンコーディングを変更することができるわけではありません。サーバーを設定しますクライアントクライアントがすべて単一のタイムゾーンエリアに固有のものではない場合は特に、タイムゾーンは通常は不可能です。 - rlb.usa

リンクされた質問


関連する質問

最近の質問