Ustaw TERAZ () jako wartość domyślną dla typu danych datetime?

197

Mam dwie kolumny w tabeli użytkowników, a mianowicie, registerDate and lastVisitDatektóre składają się z typu danych datetime. Chciałbym wykonać następujące czynności.

  1. Ustaw wartość domyślną registerDate na MySQL NOW ()
  2. Ustaw wartość domyślną lastVisitDate na 0000-00-00 00:00:00Zamiast pustej, której używa domyślnie.

Ponieważ tabela już istnieje i zawiera istniejące rekordy, chciałbym użyć tabeli Modyfikuj. Próbowałem użyć dwóch fragmentów kodu poniżej, ale żaden z nich nie działa.

ALTER TABLE users MODIFY registerDate datetime DEFAULT NOW()
ALTER TABLE users MODIFY registerDate datetime DEFAULT CURRENT_TIMESTAMP;

To daje mi błąd: ERROR 1067 (42000): Invalid default value for 'registerDate'

Czy mogę ustawić domyślną wartość daty / godziny na NOW () w MySQL?

Ibrahim Azhar Armar
źródło
4
ALTER TABLE users MODIFY dateTime timestamp default CURRENT_TIMESTAMP. Nie zdefiniowałeś data typepola w obu swoich wysiłkach
Shakti Singh
3
Ponieważ MySQL 5.6 DATEpowinien działać z wartością domyślnąNOW()
AbcAeffchen
Zgodnie z dokumentacją mysql 5.6: dev.mysql.com/doc/refman/5.6/en/data-type-defaults.html , domyślnie możesz użyć CURRENT_TIMESTAMP ().
blacktie24,
jak miałbym wdrożyć CURRENT_TIMESTAMP + 1 DZIEŃ
Ilker Baltaci

Odpowiedzi:

241

Począwszy od MySQL 5.6.5, możesz używać tego DATETIMEtypu z dynamiczną wartością domyślną:

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

Lub nawet połączyć obie zasady:

modification_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Odniesienie:
http://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available .html

Przed wersją 5.6.5 należy użyć TIMESTAMPtypu danych, który aktualizuje się automatycznie po każdej modyfikacji rekordu. Niestety, TIMESTAMPw tabeli może istnieć tylko jedno automatycznie aktualizowane pole.

CREATE TABLE mytable (
  mydate TIMESTAMP
)

Zobacz: http://dev.mysql.com/doc/refman/5.1/en/create-table.html

Jeśli chcesz uniemożliwić MySQLowi aktualizowanie wartości znacznika czasu na UPDATE(tak, aby włączała się tylko INSERT), możesz zmienić definicję na:

CREATE TABLE mytable (
  mydate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
Johan
źródło
80
naprawdę nie chcę używać znacznika czasu.
Ibrahim Azhar Armar
2
@Ibrahim: znacznik czasu jest twoją jedyną szansą. Jeśli używasz pola daty i godziny, musisz wstawiać rekord za pomocą now () za każdym razem.
Nicola Cossu
9
Podręcznik mówi jasno: „Oznacza to na przykład, że nie można ustawić domyślnej wartości dla kolumny daty jako wartości funkcji takiej jak NOW () lub CURRENT_DATE”.
Nicola Cossu
19
@Johan DATETIMEczęsto preferuje zakres, który może pomieścić: „1000-01-01 00:00:00” do „9999-12-31 23:59:59” w porównaniu do TIMESTAMPS„s” 1970-01-01 00: 00:01 'UTC do' 2038-01-19 03:14:07 'UTC. Na przykład do przechowywania dat urodzenia lub czegoś więcej niż 30 lat w przyszłości.
user17753,
5
@nickrulez Nie jesteś już ograniczony do timestamptego zachowania od MySQL 5.6
Dan Esparza
70

Używam wyzwalacza jako obejścia, aby ustawić pole daty i godziny na NOW () dla nowych wstawek:

CREATE TRIGGER `triggername` BEFORE INSERT ON  `tablename` 
FOR EACH ROW 
SET NEW.datetimefield = NOW()

powinien również działać w przypadku aktualizacji

Odpowiedzi Johana i Leonarda dotyczą konwersji na pole znacznika czasu. Chociaż jest to prawdopodobnie odpowiednie dla przypadku użycia przedstawionego w pytaniu (przechowywanie RegisterDate i LastVisitDate), nie jest to rozwiązanie uniwersalne. Zobacz pytanie datetime vs datownik .

Wardk
źródło
4
To powinna być zaakceptowana odpowiedź, ale w szczególności powinieneś ją edytować, aby było oczywiste, że dotyczy ona pola daty i godziny. Oryginalny plakat chce wiedzieć, jak go rozwiązać dla pola use a timestampdaty i godziny, i jest głupim obejściem, jeśli naprawdę poznasz różnicę między tymi dwoma typami danych.
phpguru
45

Moje rozwiązanie

ALTER TABLE `table_name` MODIFY COLUMN `column_name` TIMESTAMP NOT
NULL DEFAULT CURRENT_TIMESTAMP;
Leonardo
źródło
Ta funkcja działa, polecam wszystkim korzystanie z SQLYog lub takiego narzędzia, pozwala to robić na prostym interfejsie.
Niezmienna cegła
27
To wciąż rozwiązanie dla TIMESTAMPkolumny. Nikt nie prosił o TIMESTAMP...
Petr Peller
2
Tak, to nie jest odpowiedź na pytanie. TIMESTAMP to inny typ pola niż DATETIME.
John Hunt,
@Leonardo, jak mogę wyświetlić tylko datę
151291,
13

EUREKA !!!


Dla wszystkich, którzy stracili serce, próbując ustawić domyślną wartość DATETIME w MySQL , wiem dokładnie, jak się czujesz / czujesz. Oto on:

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

Uważnie obserwuj, że nie dodałem pojedynczych cudzysłowów / podwójnych cudzysłowów wokół zera .


Ważna aktualizacja :

Ta odpowiedź została opublikowana dawno temu. Wtedy to działało na mojej (prawdopodobnie najnowszej) instalacji MySQL i miałem ochotę go udostępnić. Przeczytaj poniższe komentarze, zanim zdecydujesz się na skorzystanie z tego rozwiązania.

Augiwan
źródło
16
To zależy od oczekiwań ... - To rozwiązanie pozwala mieć pole NIE NULL, ponieważ domyślnie jest dostępne. - To rozwiązanie nie ustawi pola na NOW ().
CodeReaper,
10
To nie odpowiada na pierwotne pytanie; odpowiedź powinna jasno to stwierdzić.
Matt Browne
2
Należy pamiętać, że TRADYCYJNY tryb SQL zawiera NO_ZERO_DATE, więc powyższe nie będzie działać w takim przypadku.
Móż
Na podstawie udzielonych odpowiedzi brzmi to tak, jakbyś nie poświęcił DATETIME jako TIMESTAMP, musisz użyć wyzwalaczy.
Chris
1
To rozwiązanie będzie trochę szalone api z „OMG to data ZERO! Co za TUTAJ! Nie możemy przekonwertować„ tego ”na java.lang.Date/System.DateTime! OMG! -Crashes-”.
Felype,
4

W wersjach mysql 5.6.5 i nowszych można używać dokładnych czasów danych oraz ustawiać wartości domyślne. Jest jednak subtelny bit, który polega na przekazaniu wartości dokładności zarówno do wywołania funkcji datetime, jak i NOW ().

Ten przykład działa:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW(6);

Ten przykład nie działa:

    ALTER TABLE my_table MODIFY created datetime(6) NOT NULL DEFAULT NOW();
Matteius
źródło
1
`ALTER TABLE  `table_name` CHANGE `column_name` 
    timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP

Może służyć do aktualizacji sygnatury czasowej podczas aktualizacji.

veelen
źródło
1

Najlepszym sposobem jest użycie „DEFAULT 0”. Inny sposób:

    /************ 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();
Lucas Moyano Angelini
źródło
0

Działa to dla mnie przy użyciu MySQL:

ALTER TABLE `table_name` MODIFY `column_name` datetime NOT NULL DEFAULT NOW();
rosshump
źródło
0
ALTER TABLE table_name
  CHANGE COLUMN date_column_name date_column_name DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

Wreszcie, to zadziałało dla mnie!

Sokole oko
źródło
0
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;
Gvs Akhil
źródło
-1

Nie jestem pewien, czy to jest nadal aktywne, ale proszę.

Jeśli chodzi o ustawienie wartości domyślnych na Now (), nie widzę, aby było to możliwe dla typu danych DATETIME. Jeśli chcesz użyć tego typu danych, ustaw datę wykonania wstawiania w następujący sposób:

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

Moja wersja mySQL to 5.5

Jerzy
źródło
7
Można uprościć jako:INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', NOW())
17753
-1

To działało dla mnie - właśnie zmieniłem INSERT na UPDATE dla mojego stołu.

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))
Różne pokolenie
źródło