ตั้งค่าทันที () เป็นค่าเริ่มต้นสำหรับประเภทข้อมูลวันที่หรือไม่


197

ฉันมีสองคอลัมน์ในผู้ใช้ตารางregisterDate and lastVisitDateซึ่งประกอบด้วยประเภทข้อมูลวันที่และเวลา ฉันต้องการทำสิ่งต่อไปนี้

  1. ตั้งค่า registerDate เป็นค่าเริ่มต้นเป็น MySQL ทันที ()
  2. ตั้ง lastVisitDate ค่าเริ่มต้นเป็น0000-00-00 00:00:00แทนที่จะเป็นโมฆะซึ่งจะใช้โดยค่าเริ่มต้น

เนื่องจากตารางมีอยู่แล้วและมีระเบียนที่มีอยู่ฉันต้องการใช้ตารางแก้ไข ฉันลองใช้รหัสสองชิ้นด้านล่าง แต่ไม่ได้ผล

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

มันทำให้ฉันมีข้อผิดพลาด: ERROR 1067 (42000): Invalid default value for 'registerDate'

เป็นไปได้ไหมที่ฉันจะตั้งค่าเริ่มต้นของวันที่และเวลาเป็น NOW () ใน MySQL?


4
ALTER TABLE users MODIFY dateTime timestamp default CURRENT_TIMESTAMP. คุณไม่ได้กำหนดdata typeเขตข้อมูลในความพยายามของคุณทั้งสอง
Shakti Singh

3
ตั้งแต่ MySQL 5.6 DATEควรทำงานกับค่าเริ่มต้นNOW()
AbcAeffchen

ตามเอกสารประกอบ mysql 5.6 นี้: dev.mysql.com/doc/refman/5.6/th/data-type-defaults.htmlคุณสามารถใช้ CURRENT_TIMESTAMP () เป็นค่าเริ่มต้น
blacktie24

ฉันจะใช้ CURRENT_TIMESTAMP อย่างไร + 1 วัน
Ilker Baltaci

คำตอบ:


241

ในฐานะของ MySQL 5.6.5 คุณสามารถใช้DATETIMEชนิดที่มีค่าเริ่มต้นแบบไดนามิก:

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

หรือรวมกฎทั้งสอง:

modification_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

การอ้างอิง:
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

ก่อนหน้า 5.6.5 คุณต้องใช้TIMESTAMPประเภทข้อมูลซึ่งจะอัปเดตโดยอัตโนมัติเมื่อใดก็ตามที่มีการแก้ไขเรคคอร์ด อย่างไรก็ตามมีเพียงหนึ่งTIMESTAMPฟิลด์ที่อัปเดตอัตโนมัติเท่านั้นที่มีอยู่ต่อตาราง

CREATE TABLE mytable (
  mydate TIMESTAMP
)

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

หากคุณต้องการป้องกันไม่ให้ MySQL อัปเดตค่าการประทับเวลาเปิดUPDATE(เพื่อให้เป็นเพียงทริกเกอร์เปิดINSERT) คุณสามารถเปลี่ยนคำจำกัดความเป็น:

CREATE TABLE mytable (
  mydate TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)

80
ฉันไม่ต้องการใช้การประทับเวลา
Ibrahim Azhar Armar

2
@ อิบราฮิม: การประทับเวลาเป็นโอกาสเดียวของคุณ หากคุณใช้เขตข้อมูลวันที่และเวลาคุณต้องแทรกบันทึกโดยใช้ตอนนี้ () ทุกครั้ง
Nicola Cossu

9
พูดด้วยตนเองชัดเจน: "ซึ่งหมายความว่าตัวอย่างเช่นคุณไม่สามารถตั้งค่าเริ่มต้นสำหรับคอลัมน์วันที่ให้เป็นค่าของฟังก์ชั่นเช่น NOW () หรือ CURRENT_DATE"
Nicola Cossu

20
@Johan DATETIMEมักชอบที่จะทำช่วงที่สามารถเก็บได้: '1,000-01-01 00:00:00' ถึง '9999-12-31 23:59:59' เมื่อเทียบกับTIMESTAMPS's' 1970-01-01 00: 00:01 'UTC ถึง' 2038-01-19 03:14:07 'UTC สำหรับวัตถุประสงค์ในการจัดเก็บวันเกิดหรืออะไรมากกว่า 30 ปีในอนาคตเช่น
user17753

5
@nickrulez คุณไม่ได้ถูก จำกัดtimestampสำหรับพฤติกรรมนี้ตั้งแต่ MySQL 5.6
Dan Esparza

70

ฉันใช้ทริกเกอร์เป็นวิธีแก้ปัญหาเพื่อตั้งค่าฟิลด์ datetime เป็น NOW () สำหรับส่วนแทรกใหม่:

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

ควรทำงานเพื่อรับการอัปเดตด้วย

รู้รอบโดย Johan & Leonardo เกี่ยวข้องกับการแปลงเป็นเขตเวลา แม้ว่านี่อาจจะใช้ได้สำหรับกรณีการใช้งานที่แสดงในคำถาม (การจัดเก็บ RegisterDate และ LastVisitDate) แต่ก็ไม่ใช่วิธีการแก้ปัญหาสากล ดูคำถามdatetime vs timestamp


4
นี่ควรเป็นคำตอบที่ได้รับการยอมรับ แต่โดยเฉพาะคุณควรแก้ไขเพื่อให้ชัดเจนว่าเป็นฟิลด์ datetime โปสเตอร์ต้นฉบับต้องการทราบวิธีแก้ปัญหาสำหรับฟิลด์ datetime และuse a timestampเป็นวิธีการแก้ปัญหาที่โง่ถ้าคุณเรียนรู้ความแตกต่างระหว่างสองชนิดข้อมูลเหล่านี้
phpguru

45

ทางออกของฉัน

ALTER TABLE `table_name` MODIFY COLUMN `column_name` TIMESTAMP NOT
NULL DEFAULT CURRENT_TIMESTAMP;

def นี้ใช้งานได้ผมขอแนะนำให้ทุกคนใช้ SQLYog หรือเครื่องมือแบบนี้ช่วยให้คุณทำสิ่งนี้ได้บนส่วนต่อประสานที่ใช้งานง่าย
Brick ไม่เปลี่ยนรูป

27
นี่ยังคงเป็นทางออกสำหรับTIMESTAMPคอลัมน์ ไม่มีใครขอTIMESTAMP...
Petr Peller

2
ใช่นี่ไม่ใช่คำตอบสำหรับคำถาม TIMESTAMP เป็นเขตข้อมูลประเภทอื่นไปที่ DATETIME
John Hunt


13

EUREKA !!!


สำหรับผู้ที่สูญเสียใจพยายามตั้งค่าเริ่มต้น DATETIME ใน MySQLฉันรู้ว่าคุณรู้สึกอย่างไร / รู้สึก ดังนั้นนี่คือ:

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

อย่างสังเกตว่าผมยังไม่ได้เพิ่มราคาเดียว / คำพูดสองรอบ0


การอัปเดตที่สำคัญ :

คำตอบนี้ถูกโพสต์มานานแล้ว ก่อนหน้านี้มันใช้งานได้กับการติดตั้ง MySQL ของฉันและฉันรู้สึกอยากแบ่งปัน โปรดอ่านความคิดเห็นด้านล่างก่อนที่คุณจะตัดสินใจใช้โซลูชันนี้ทันที


16
ขึ้นอยู่กับความคาดหวัง ... - วิธีนี้ช่วยให้คุณมีฟิลด์ไม่เป็นโมฆะเนื่องจากมีการระบุค่าเริ่มต้นไว้ - วิธีนี้จะไม่ตั้งค่าฟิลด์เป็น NOW ()
CodeReaper

10
สิ่งนี้ไม่ตอบคำถามเดิม คำตอบควรระบุอย่างชัดเจน
Matt Browne

2
โปรดทราบว่าโหมด SQL แบบดั้งเดิมมี NO_ZERO_DATE ดังนั้นข้างต้นจะไม่ทำงานในกรณีนั้น
Moz

ตามคำตอบที่ให้มาดูเหมือนว่าคุณจะไม่เสียสละเวลา DATETIME เพื่อเป็น TIMESTAMP ดังนั้นคุณต้องใช้ทริกเกอร์
Chris

1
วิธีการแก้ปัญหานี้จะมี apis คลั่งไคล้กับ "OMG เป็นวันที่ ZERO! HERESY! เราไม่สามารถแปลง 'this' เป็น java.lang.Date/System.DateTime! OMG! -crashes-"
Felype

4

mysql 5.6 docs บอกว่า CURRENT_TIMESTAMP สามารถใช้เป็นค่าเริ่มต้นสำหรับทั้งชนิดข้อมูล TIMESTAMP และ DATETIME:

http://dev.mysql.com/doc/refman/5.6/en/timestamp-initialization.html


ตรงจาก 5.6.5 เพราะฉันมี 5.6.22 และมันไม่ทำงานถ้ามันเป็น 5.6 .. แย่เกินไป
Delphine

4

ในรุ่น mysql 5.6.5 และใหม่กว่าคุณสามารถใช้ชุดข้อมูลที่แม่นยำและตั้งค่าเริ่มต้นได้เช่นกัน มีบิตที่บอบบางซึ่งจะส่งผ่านค่าความแม่นยำทั้งวันที่และเวลาและการเรียกใช้ฟังก์ชัน NOW ()

ตัวอย่างนี้ใช้งานได้:

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

ตัวอย่างนี้ไม่ทำงาน:

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

1
`ALTER TABLE  `table_name` CHANGE `column_name` 
    timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
    ON UPDATE CURRENT_TIMESTAMP

สามารถใช้เพื่ออัปเดตการประทับเวลาในการอัปเดต


1

วิธีที่ดีที่สุดคือใช้ "DEFAULT 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:

ALTER TABLE `table_name` MODIFY `column_name` datetime NOT NULL DEFAULT NOW();

0
ALTER TABLE table_name
  CHANGE COLUMN date_column_name date_column_name DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;

ในที่สุดสิ่งนี้ได้ผลสำหรับฉัน!


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;

-1

ไม่แน่ใจว่านี่ยังใช้งานได้หรือไม่

เกี่ยวกับการตั้งค่าเริ่มต้นเป็น Now () ฉันไม่เห็นว่าเป็นไปได้สำหรับประเภทข้อมูล DATETIME หากคุณต้องการใช้ชนิดข้อมูลนั้นให้ตั้งวันที่เมื่อคุณทำการแทรกเช่นนี้

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

MySQL เวอร์ชั่นของฉันคือ 5.5


7
สามารถลดความซับซ้อนได้ดังนี้:INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', NOW())
17753

-1

สิ่งนี้ใช้ได้ผลสำหรับฉัน - เพิ่งเปลี่ยน INSERT เป็น UPDATE สำหรับตารางของฉัน

INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.