คุณจะตั้งค่าเริ่มต้นสำหรับคอลัมน์ MySQL Datetime ได้อย่างไร?
ใน SQL Server getdate()มัน อะไรคือสิ่งที่เทียบเท่ากับ MySQL? ฉันใช้ MySQL 5.x ถ้านั่นเป็นปัจจัย
คุณจะตั้งค่าเริ่มต้นสำหรับคอลัมน์ MySQL Datetime ได้อย่างไร?
ใน SQL Server getdate()มัน อะไรคือสิ่งที่เทียบเท่ากับ MySQL? ฉันใช้ MySQL 5.x ถ้านั่นเป็นปัจจัย
คำตอบ:
การแก้ไขที่สำคัญ: ตอนนี้เป็นไปได้ที่จะบรรลุสิ่งนี้กับเขตข้อมูล 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>
** CAVEAT: หากคุณกำหนดคอลัมน์ด้วย CURRENT_TIMESTAMP ON เป็นค่าเริ่มต้นคุณจะต้องระบุค่าสำหรับคอลัมน์นี้เสมอหรือค่าจะรีเซ็ตตัวเองเป็น "ทันที ()" ในการอัปเดต ซึ่งหมายความว่าหากคุณไม่ต้องการให้ค่าเปลี่ยนแปลงคำสั่ง UPDATE ของคุณจะต้องมี "[ชื่อคอลัมน์ของคุณ] = [ชื่อคอลัมน์ของคุณ]" (หรือค่าอื่น ๆ ) หรือค่าจะกลายเป็น "ตอนนี้ ()" แปลก แต่จริง ฉันหวังว่านี่จะช่วยได้. ฉันใช้ 5.5.56-MariaDB **
DATEคอลัมน์? (ไม่ใช่datetimeคอลัมน์)
ในเวอร์ชัน 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
dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
MySQL ( ก่อนหน้ารุ่น 5.6.5 ) ไม่อนุญาตให้ใช้ฟังก์ชั่นสำหรับค่า DateTime ที่เป็นค่าเริ่มต้น TIMESTAMP ไม่เหมาะเนื่องจากมีพฤติกรรมแปลก ๆ และไม่แนะนำให้ใช้เป็นข้อมูลอินพุต (ดูค่าเริ่มต้นของประเภทข้อมูล MySQL )
ที่กล่าวว่าคุณสามารถทำได้โดยการสร้าง Triggerโดยการสร้างทริกเกอร์
ฉันมีตารางที่มีเขตข้อมูล DateCreated ประเภท DateTime ฉันสร้างทริกเกอร์ในตาราง "Before Insert" และ "SET NEW.DateCreated=NOW() " และใช้งานได้ดี
ฉันหวังว่านี่จะช่วยใครซักคน
IF NEW.created_at IS NOT NULL
สำหรับฉันแล้ววิธีการกระตุ้นทำงานได้ดีที่สุด แต่ฉันพบอุปสรรค์กับวิธีการนั้น พิจารณาทริกเกอร์พื้นฐานเพื่อตั้งค่าฟิลด์วันที่เป็นเวลาปัจจุบันในการแทรก:
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 - yuck! เมื่อต้องการแทนที่ลักษณะการทำงานนี้เมื่อมีการจัดเตรียมค่าลองทริกเกอร์การแก้ไขเล็กน้อยนี้ด้วยตัวดำเนินการ IFNULL:
CREATE TRIGGER myTable_OnInsert BEFORE INSERT ON `tblMyTable`
FOR EACH ROW SET NEW.dateAdded = IFNULL(NEW.dateAdded, NOW());
สิ่งนี้ให้สิ่งที่ดีที่สุดทั้งสองโลก: คุณสามารถระบุค่าสำหรับคอลัมน์วันที่ของคุณและจะใช้เวลามิฉะนั้นจะเริ่มต้นตามเวลาปัจจุบัน มันยังคงเป็นสลัมเมื่อเทียบกับสิ่งที่สะอาดอย่าง DEFAULT GETDATE () ในคำจำกัดความของตาราง แต่เราใกล้เข้ามามากขึ้น!
NULLลืมที่จะตั้งค่าเขตข้อมูลที่จะอนุญาตให้ ไม่มีคำเตือนอีกต่อไป
dateAddedจะแสดง '0000-00-00 00:00:00' ทั้งหมด การใช้วิธีการนี้ใช้เคล็ดลับ: `สำหรับแต่ละแถวถ้า NEW.dateAdded = 0 แล้ว NEW.dateAdded = NOW (); END IF; `
ฉันสามารถแก้ปัญหานี้โดยใช้คำสั่งแก้ไขนี้บนโต๊ะของฉันที่มีสองวันที่และเวลา
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 ส่งผลให้ค่าการประทับเวลาที่สมบูรณ์แบบในทั้งสองฟิลด์ การอัพเดตแถวใด ๆ จะมีการเปลี่ยนแปลง หากคุณแทรกระเบียนผ่านเบราว์เซอร์แบบสอบถาม MySQL ที่คุณต้องการอีกหนึ่งขั้นตอนทริกเกอร์เพื่อจัดการ 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]
คุณสามารถใช้ทริกเกอร์เพื่อทำสิ่งประเภทนี้
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;
สำหรับผู้ที่สูญเสียใจพยายามตั้งค่าเริ่มต้นDATETIMEในMySQLฉันรู้ว่าคุณรู้สึกอย่างไร / รู้สึก ดังนั้นนี่คือ:
ALTER TABLE `table_name` CHANGE `column_name` DATETIME NOT NULL DEFAULT 0
โปรดสังเกตว่าฉันไม่ได้เพิ่มเครื่องหมายคำพูดเดี่ยว / เครื่องหมายคำพูดคู่ล้อมรอบ0
ฉันกำลังกระโดดหลังจากแก้ปัญหานี้แล้ว: D
ALTER TABLE zones MODIFY created datetime NOT NULL DEFAULT 0;
MySQL 5.6 ได้แก้ไขปัญหานี้แล้ว
ALTER TABLE mytable CHANGE mydate datetime NOT NULL DEFAULT 'CURRENT_TIMESTAMP'
หากคุณได้สร้างตารางแล้วคุณสามารถใช้
เพื่อเปลี่ยนค่าเริ่มต้นเป็นเวลาวันที่ปัจจุบัน
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';
นี่เป็นข่าวร้ายจริงๆ ที่นี่เป็นคำขอข้อผิดพลาด / คุณลักษณะยาวรอการนี้ การสนทนานั้นยังพูดถึงข้อ จำกัด ของชนิดข้อมูลการประทับเวลา
ฉันสงสัยอย่างจริงจังว่าอะไรคือปัญหาของการนำสิ่งนี้ไปใช้
ฉันใช้ 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'
เพียงแค่ผลงาน
ในฐานะsidenoteมันถูกกล่าวถึงในmysql docs :
ประเภท DATE ใช้สำหรับค่าที่มีส่วนวันที่ แต่ไม่มีส่วนเวลา MySQL ดึงและแสดงค่า DATE ในรูปแบบ 'YYYY-MM-DD' ช่วงที่รองรับคือ '1000-01-01' ถึง '9999-12-31'
แม้ว่าพวกเขาจะพูดว่า:
ค่า DATE, DATETIME หรือ TIMESTAMP ไม่ถูกต้องจะถูกแปลงเป็นค่า“ ศูนย์” ของประเภทที่เหมาะสม ('0000-00-00' หรือ '0000-00-00 00:00:00')
คุณสามารถใช้ตอนนี้ () เพื่อตั้งค่าของคอลัมน์วันที่และเวลาได้ แต่โปรดจำไว้ว่าคุณไม่สามารถใช้มันเป็นค่าเริ่มต้น
NOW()และใช้ในภายหลังสำหรับการแทรก สำหรับเวอร์ชั่น 5.6 ให้ตั้งNOW()เป็นค่าเริ่มต้น
สำหรับทุกคนที่ใช้คอลัมน์ TIMESTAMP เป็นวิธีแก้ปัญหาฉันต้องการ จำกัด ข้อ จำกัด ต่อไปนี้จากคู่มือ:
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 เป็นจุดสิ้นสุดของทริกเกอร์และสร้างข้อผิดพลาด เช่น
DELIMITER //
CREATE TRIGGER `MyTable_UPDATE` BEFORE UPDATE ON `MyTable`
FOR EACH ROW BEGIN
-- Set the udpate date
Set new.UpdateDate = now();
END//
DELIMITER ;
นี่คือวิธีทำบน MySQL 5.1:
ALTER TABLE `table_name` CHANGE `column_name` `column_name`
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
ฉันไม่รู้ว่าทำไมคุณต้องป้อนชื่อคอลัมน์สองครั้ง
แม้ว่าคุณจะไม่สามารถทำได้ด้วยDATETIMEคำจำกัดความเริ่มต้นคุณสามารถรวมคำสั่ง select ในคำสั่งแทรกของคุณเช่นนี้:
INSERT INTO Yourtable (Field1, YourDateField) VALUES('val1', (select now()))
สังเกตการขาดเครื่องหมายคำพูดรอบ ๆ ตาราง
สำหรับ MySQL 5.5
หากคุณพยายามตั้งค่าเริ่มต้นเป็น NOW () ฉันไม่คิดว่า MySQL รองรับสิ่งนั้น ใน MySQL คุณไม่สามารถใช้ฟังก์ชันหรือนิพจน์เป็นค่าเริ่มต้นสำหรับคอลัมน์ประเภทใดก็ได้ยกเว้นคอลัมน์ชนิดข้อมูล TIMESTAMP ซึ่งคุณสามารถระบุ CURRENT_TIMESTAMP เป็นค่าเริ่มต้น
ฉันคิดว่ามันง่ายใน mysql ตั้งแต่ mysql ฟังก์ชั่น inbuilt เรียกว่าตอนนี้ () ซึ่งให้เวลาปัจจุบัน (เวลาของการแทรกนั้น)
ดังนั้นข้อความค้นหาของคุณควรมีลักษณะคล้ายกัน
CREATE TABLE defaultforTime(
`creation_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`modification_time` DATETIME default now()
);
ขอบคุณ.
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
ใช้รหัสต่อไปนี้
DELIMITER $$
CREATE TRIGGER bu_table1_each BEFORE UPDATE ON table1 FOR EACH ROW
BEGIN
SET new.datefield = NOW();
END $$
DELIMITER ;
หากคุณพยายามตั้งค่าเริ่มต้นเป็น NOW (), MySQL รองรับว่าคุณต้องเปลี่ยนประเภทของคอลัมน์ TIMESTAMP แทน DATETIME TIMESTAMP มีวันที่และเวลาปัจจุบันตามค่าเริ่มต้น .. ฉันคิดว่ามันจะช่วยแก้ปัญหาของคุณได้ ..
ทำเช่นถ้าฉันมีตารางชื่อ 'เว็บไซต์' กับ created_at และคอลัมน์ update_at ที่ทั้ง DATETIME และต้องการค่าเริ่มต้นตอนนี้ฉันสามารถรัน sql ต่อไปนี้เพื่อให้บรรลุนี้
เปลี่ยนตาราง `site 'CHANGE` created_at`` created_at` TIMESTAMP ไม่เป็นโมฆะค่าเริ่มต้น CURRENT_TIMESTAMP; เปลี่ยนตาราง `site 'CHANGE` created_at`` created_at` DATETIME NULL ค่าเริ่มต้น NULL; เปลี่ยนตาราง `site` CHANGE` updated_at`` updated_at` TIMESTAMP ไม่เป็นโมฆะเริ่มต้น CURRENT_TIMESTAMP; เปลี่ยนตาราง `site 'เปลี่ยน` updated_at`' updated_at` DATETIME NULL ค่าเริ่มต้น NULL;
ลำดับของคำสั่งมีความสำคัญเนื่องจากตารางไม่สามารถมีสองคอลัมน์ประเภท TIMESTAMP ที่มีค่าเริ่มต้นของ CUREENT TIMESTAMP
นี่คือตัวอย่างทริกเกอร์ของฉัน:
/************ 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();
ทำงานได้ดีกับ 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;
คุณสามารถแก้ไขการประทับเวลาเริ่มต้น ก่อนอื่นให้พิจารณาชุดอักขระที่คุณใช้ตัวอย่างเช่นถ้าคุณถ่าย utf8 ชุดอักขระนี้รองรับทุกภาษาและหากคุณใช้ laten1 ชุดอักขระนี้รองรับเฉพาะภาษาอังกฤษเท่านั้น setp ถัดไปหากคุณทำงานภายใต้โครงการใด ๆ ที่คุณควรทราบเขตเวลาของลูกค้าและเลือกว่าคุณเป็นเขตลูกค้า ขั้นตอนนี้เป็นสิ่งจำเป็น