Bagaimana Anda menetapkan nilai default untuk kolom MySQL Datetime?


898

Bagaimana Anda menetapkan nilai default untuk kolom MySQL Datetime?

Dalam SQL Server getdate(). Apa yang setara untuk MySQL? Saya menggunakan MySQL 5.x jika itu merupakan faktor.


4
Saya menggunakan CURRENT_TIMESTAMP di tabel mysql saya (tidak dalam kueri), mungkin ini bisa membantu juga.
Ruben

15
Fitur ini sekarang telah ditambahkan ke MySQL 5.6.5. Semoga ini bisa membantu seseorang. optimize-this.blogspot.co.uk/2012/04/...
GhostInTheSecureShell

@GhostInTheSecureShell cukup misi untuk menginstalnya, setidaknya di Debian, tapi jelas fitur yang luar biasa. Saya pikir pada akhirnya semua pertanyaan "dua CURRENT_TIMESTAMP" ini akan berkurang!
Marc DiMillo

sekarang fungsi () atau Anda dapat melakukan dengan pengaturan default pada tingkat kolom.
Anshul Sharma

Jawaban:


862

EDIT PENTING: Sekarang dimungkinkan untuk mencapai ini dengan bidang DATETIME sejak MySQL 5.6.5 , lihat posting lain di bawah ini ...

Versi sebelumnya tidak dapat melakukannya dengan DATETIME ...

Tetapi Anda dapat melakukannya dengan 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>

** CAVEAT: JIKA Anda menetapkan kolom dengan CURRENT_TIMESTAMP ON sebagai default, Anda perlu SELALU menentukan nilai untuk kolom ini atau nilai akan secara otomatis mengatur ulang sendiri ke "sekarang ()" pada pembaruan. Ini berarti bahwa jika Anda tidak ingin nilai berubah, pernyataan UPDATE Anda harus mengandung "[nama kolom Anda] = [nama kolom Anda]" (atau nilai lain) atau nilainya akan menjadi "sekarang ()". Aneh, tapi benar. Saya harap ini membantu. Saya menggunakan 5.5.56-MariaDB **


400
Penting untuk dicatat bahwa datetime memiliki rentang 1000-9999, tetapi rentang untuk cap waktu hanya 1970-2038 . ini bisa menjadi masalah jika sistem Anda harus menyimpan tanggal lahir, atau Anda harus menangani sesuatu seperti rencana pembayaran hipotek 30 tahun. dev.mysql.com/doc/refman/5.0/id/datetime.html
Kip

13
Berhati-hatilah juga dengan stempel waktu karena pembaruan otomatis secara ajaib ... lihat jawaban berikutnya stackoverflow.com/a/1483959/233906
Cerber

6
Hal ini mungkin dari versi 5.6.5, lihat jawaban Gustav di bawah ini (saya menyadari jawaban Anda telah diposting ketika MySQL masih 5.0!)
e2-e4

4
@ Tip, Hai, apakah mungkin untuk memiliki nilai default untuk DATEkolom? (bukan datetimekolom).
Sajib Acharya

ti sepertinya tidak mungkin untuk kolom DATE: Anda harus menggunakan tipe data DATETIME
Fabio Napodano

599

Dalam versi 5.6.5, dimungkinkan untuk menetapkan nilai default pada kolom datetime, dan bahkan membuat kolom yang akan diperbarui ketika baris diperbarui. Definisi tipe:

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

Referensi: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html


3
Nilai default untuk 'menu_creation_time' tidak valid
Fernando Trindade

2
@FernandoTrindade Anda perlu MySQL versi 5.6.5 atau lebih baru. Anda dapat melihatnya bekerja di sini: sqlfiddle.com/#!9/dd2be
Gustav Bertram

1
@GustavBertram, saya menggunakan versi 5.6.22, tetapi masih ada kesalahan sebagai berikut: CREATE TABLE tbl (InsertDate DATETIME BUKAN NULL DEFAULT CURRENT_TIMESTAMP, UpdateDATE TIMESTAMP NULL DI UPDATE CURRENT_TIMESTAMP (6)); Kode Kesalahan: 1294. Klausa UPDATE ONDATE tidak valid untuk kolom 'UpdateDate'
Manish Sapkal

@ManishSapkal Anda menggunakan TIMESTAMP, bukan DATETIME. Juga, jangan membuatnya NULL.
Gustav Bertram

1
Saya pikir sintaks "PADA PEMBARUAN" salah. Menurut dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html seharusnyadt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
Dan Bough

148

MySQL ( sebelum versi 5.6.5 ) tidak memungkinkan fungsi digunakan untuk nilai DateTime default. TIMESTAMP tidak cocok karena perilakunya yang aneh dan tidak direkomendasikan untuk digunakan sebagai data input. (Lihat Default Tipe Data MySQL .)

Yang mengatakan, Anda dapat mencapai ini dengan membuat Pemicu .

Saya punya tabel dengan bidang DateCreated dari tipe DateTime. Saya membuat pemicu pada tabel itu "Sebelum Sisipkan" dan " SET NEW.DateCreated=NOW()" dan itu berfungsi dengan baik.

Saya harap ini membantu seseorang.


21
BUAT TRIGGER trigger_foo_SetCreatedAt SEBELUM MASUKKAN SETIAP UNTUK SETIAP SET SET BARIS.created_at = UTC_TIMESTAMP ();
kgriff

5
Anda mungkin lebih baik menggunakan stempel waktu daripada pemicu kewarasan masa depan (pemeliharaan). Ini terlalu sepele kasus penggunaan untuk pemicu, meskipun merupakan solusi.
getWeberForStackExchange

8
Anda mungkin hanya ingin menetapkan nilai defaultIF NEW.created_at IS NOT NULL
Petr Peller

132

Bagi saya pendekatan pemicu telah bekerja yang terbaik, tetapi saya menemukan hambatan dengan pendekatan itu. Pertimbangkan pemicu dasar untuk menetapkan bidang tanggal ke waktu saat ini pada saat memasukkan:

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

Ini biasanya hebat, tetapi katakan Anda ingin mengatur bidang secara manual melalui pernyataan INSERT, seperti:

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

Apa yang terjadi adalah bahwa pemicu segera menimpa nilai yang Anda berikan untuk bidang tersebut, dan satu-satunya cara untuk menetapkan waktu tidak saat ini adalah tindak lanjut pernyataan UPDATE - yuck! Untuk mengganti perilaku ini ketika nilai diberikan, coba pemicu yang sedikit dimodifikasi ini dengan operator IFNULL:

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

Ini memberikan yang terbaik dari kedua dunia: Anda dapat memberikan nilai untuk kolom tanggal Anda dan akan dibutuhkan, dan jika tidak maka akan default ke waktu saat ini. Ini masih ghetto relatif terhadap sesuatu yang bersih seperti DEFAULT GETDATE () dalam definisi tabel, tapi kami semakin dekat!


5
+1 untuk mengakui peringatan dengan menimpa nilai pengguna eksplisit pada sisipan.
Kip

2
Saya pribadi berpikir ini adalah cara terbaik untuk pergi. TIMESTAMP memang memiliki perilaku aneh dan saya tidak akan pernah menulis kode yang memiliki batasan 2038 tahun.
Eric

Sudahlah, aku sudah menemukan jawabannya. Lupa mengatur bidang yang diizinkan NULL. Tidak ada peringatan lagi.
Kaji

Pemicu itu jahat! Hanya pernah menggunakannya ketika tidak ada cara lain untuk melakukan sesuatu. Lebih baik meng-upgrade ke 5.6.x id daripada menggunakan pemicu.
ksymeon

4
Di MySQL 5.5 IFNULL tidak berfungsi pada DATETIME; menggunakan pemicu di atas dateAddedakan menampilkan semua '0000-00-00 00:00:00'. Menggunakan ini berguna: `UNTUK SETIAP ROW JIKA BARU.dateAdded = 0 KEMUDIAN SET NEW.dateAdded = SEKARANG (); AKHIR JIKA; `
Kenney

28

Saya bisa menyelesaikan ini menggunakan pernyataan perubahan ini di meja saya yang memiliki dua bidang datetime.

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;

Ini berfungsi seperti yang Anda harapkan berfungsi sekarang () berfungsi. Memasukkan nulls atau mengabaikan bidang Created_dt dan updated_dt menghasilkan nilai cap waktu yang sempurna di kedua bidang. Pembaruan apa pun pada baris akan mengubah updated_dt. Jika Anda menyisipkan catatan melalui browser kueri MySQL Anda memerlukan satu langkah lagi, pemicu untuk menangani Created_dt dengan cap waktu baru.

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

Pemicunya bisa apa saja yang Anda inginkan. Saya suka konvensi penamaan [trig] _ [my_table_name] _ [masukkan]


Saya bermaksud mengatakan, Jika Anda memasukkan catatan melalui browser permintaan MySQL secara manual melalui grid tanpa pernyataan insert () pemicu diperlukan. Jika Anda selalu menggunakan pernyataan sisipan, pemicunya sama sekali tidak perlu.

Aduh! Maksud saya pemicu (nama) dapat menjadi apa pun yang Anda inginkan karena nama pemicu tidak mempengaruhi fungsi sama sekali. Kebanyakan orang akan tahu itu, tapi beberapa orang baru untuk MySQL mungkin tidak tahu ...

Astaga, maaf tentang kurangnya jeda baris. Gunakan tanda titik dua untuk menandai akhir setiap baris.

24

Anda dapat menggunakan pemicu untuk melakukan hal semacam ini.

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

Untuk semua yang kehilangan hati mencoba untuk menetapkan nilai DATETIME default di MySQL , saya tahu persis bagaimana perasaan Anda / rasakan. Jadi di sini adalah:

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

Hati-hati mengamati bahwa saya belum menambahkan tanda kutip tunggal / tanda kutip ganda sekitar 0

Saya benar-benar melompat setelah memecahkan yang ini: D


8
Itu tidak memasukkan waktu tidak saat ini. Ini akan memasukkan '0000-00-00 00:00:00'.
Pit Digger

8
Saya tidak mengatakan itu mengatur waktu saat ini. Banyak ppl sedang / sedang mencoba untuk menetapkan nilai nol default, tetapi itu tidak berfungsi. Kita perlu menghilangkan tanda kutip. Karena temuan ini menyebabkan banyak waktu dan frustrasi, saya berpikir untuk membaginya dengan masyarakat. Orang-orang seperti Anda bertanggung jawab atas pengguna yang kehilangan minat untuk berbagi info bermanfaat dengan orang lain. Saya benar-benar tidak melihat alasan untuk mendapatkan -1! Masa bodo.
Augiwan

3
Hal yang sama dapat dicapai dengan DATETIME NOT NULL.
Brendan Byrd

Ada satu lagi karakter `di dalam contoh perintah sql, yang tidak dapat saya edit, karena itu hanya edit satu karakter.
quapka

kode Anda tidak bekerja untuk saya, inilah yang berhasilALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
Smith


14

Jika Anda sudah membuat tabel maka Anda bisa menggunakannya

Untuk mengubah nilai default ke waktu tanggal saat ini

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

Untuk mengubah nilai default ke '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

Saya menjalankan MySql Server 5.7.11 dan kalimat ini:

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

adalah tidak bekerja. Namun berikut ini:

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

hanya bekerja .

Sebagai sidenote , disebutkan dalam dokumen mysql :

Tipe DATE digunakan untuk nilai-nilai dengan bagian tanggal tetapi tanpa bagian waktu. MySQL mengambil dan menampilkan nilai DATE dalam format 'YYYY-MM-DD'. Kisaran yang didukung adalah '1000-01-01' hingga '9999-12-31'.

bahkan jika mereka juga mengatakan:

Nilai DATE, DATETIME, atau TIMESTAMP tidak valid dikonversi ke nilai "nol" dari jenis yang sesuai ('0000-00-00' atau '0000-00-00 00:00:00').


8

Anda dapat menggunakan now () untuk mengatur nilai kolom datetime, tetapi perlu diingat bahwa Anda tidak dapat menggunakannya sebagai nilai default.


4
benar. Saya baru saja mencoba menggunakan sekarang dan mendapat kesalahan "Kode Kesalahan: 1067. Nilai default tidak valid.". jadi apa jawabannya? ;-)
Brian Boatright

Ini adalah solusi terbaik untuk kompromi versi MySQL 5.5 dan 5.6. Untuk versi 5.5, tentukan sebelumnya nilai NOW()dan gunakan nanti untuk penyisipan. Untuk versi 5.6, cukup tetapkan NOW()sebagai nilai default.
Abel Callejo

8

Untuk semua yang menggunakan kolom TIMESTAMP sebagai solusi, saya ingin membatasi kedua batasan berikut dari manual:

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

"Tipe data TIMESTAMP memiliki rentang '1970-01-01 00:00:01' UTC hingga ' 2038-01-19 03:14:07 ' UTC. Ini memiliki berbagai properti, tergantung pada versi MySQL dan SQL mode server sedang berjalan masuk. Properti ini dijelaskan nanti di bagian ini. "

Jadi ini jelas akan merusak perangkat lunak Anda dalam sekitar 28 tahun.

Saya percaya satu-satunya solusi di sisi database adalah menggunakan pemicu seperti yang disebutkan dalam jawaban lain.


2
Bagaimana jika MySQL diperbarui 20 tahun dari sekarang dan batasan itu dihapus? Saya tidak yakin apakah itu mungkin tetapi hanya sebuah pemikiran.
NessDan

7

Sementara mendefinisikan pemicu multi-baris kita harus mengubah pembatas sebagai titik koma akan diambil oleh kompiler MySQL sebagai akhir dari pemicu dan menghasilkan kesalahan. misalnya

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

5

Berikut ini cara melakukannya di MySQL 5.1:

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

Saya tidak tahu mengapa Anda harus memasukkan nama kolom dua kali.


5
Ganti juga untuk mengganti nama bidang. Nama kolom pertama adalah 'lama', nama kolom kedua adalah 'baru'. Itu terlihat berlebihan jika Anda tidak mengubah nama bidang. Jika terlalu tidak menyenangkan, cobalah MODIFY.
John Gordon

5

Meskipun Anda tidak dapat melakukan ini dengan DATETIMEdalam definisi default, Anda dapat dengan mudah memasukkan pernyataan pilih dalam pernyataan insert Anda seperti ini:

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

Perhatikan kurangnya kutipan di sekitar tabel.

Untuk MySQL 5.5


3

Jika Anda mencoba menetapkan nilai default sebagai SEKARANG (), saya tidak berpikir MySQL mendukungnya. Di MySQL, Anda tidak dapat menggunakan fungsi atau ekspresi sebagai nilai default untuk semua jenis kolom, kecuali untuk kolom tipe data TIMESTAMP, yang untuknya Anda dapat menentukan CURRENT_TIMESTAMP sebagai default.


3

Saya pikir itu sederhana di mysql karena mysql fungsi inbuilt disebut sekarang () yang memberikan waktu saat ini (waktu memasukkan itu).

Jadi permintaan Anda akan terlihat seperti itu

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

Terima kasih.


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

Dalam kueri di atas untuk membuat 'testtable', saya menggunakan '1999-12-12 12:12:12' sebagai nilai default untuk kolom DATETIME colname


1

Gunakan kode berikut

DELIMITER $$

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

    DELIMITER ;

0

Jika Anda mencoba untuk menetapkan nilai default sebagai SEKARANG (), MySQL mendukung bahwa Anda harus mengubah jenis kolom TIMESTAMP alih-alih DATETIME. TIMESTAMP memiliki tanggal dan waktu saat ini sebagai default..saya pikir itu akan menyelesaikan masalah Anda ..


0

Ambil contoh Jika saya memiliki tabel bernama 'situs' dengan kolom create_at dan update_at yang keduanya DATETIME dan memerlukan nilai default sekarang, saya bisa menjalankan sql berikut untuk mencapai ini.

ALTER TABEL `situs` PERUBAHAN` Created_at` `Created_at` TIMESTAMP BUKAN NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABEL `situs` PERUBAHAN` Created_at` `Created_at` DATETIME NULL DEFAULT NULL;

ALTER TABEL `situs` PERUBAHAN` updated_at` `updated_at` TIMESTAMP BUKAN NULL DEFAULT CURRENT_TIMESTAMP;

ALTER TABEL `situs` PERUBAHAN` updated_at` `updated_at` DATETIME NULL DEFAULT NULL;

Urutan pernyataan penting karena sebuah tabel tidak dapat memiliki dua kolom tipe TIMESTAMP dengan nilai default CUREENT TIMESTAMP


0

Ini adalah contoh pemicu saya:

/************ 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

Bekerja dengan baik dengan 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

Anda dapat menyelesaikan cap waktu default. Pertama-tama pertimbangkan set karakter mana yang Anda gunakan misalnya jika Anda menggunakan utf8 set karakter ini mendukung semua bahasa dan jika Anda menggunakan laten1, set karakter ini hanya mendukung bahasa Inggris. Setp berikutnya jika Anda bekerja di bawah proyek apa pun Anda harus tahu zona waktu klien dan memilih Anda zona klien. Langkah ini wajib.


2
Kolom DateTime tidak dapat memiliki nilai default. Ini didokumentasikan 'fitur'. Tidak semua pengembang memiliki akses untuk mengubah pengkodean karakter mereka. Dan pengaturan server untuk zona waktu klien biasanya tidak memungkinkan, terutama ketika klien tidak semuanya asli untuk satu zona waktu tunggal.
rlb.usa
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.