คุณจะตั้งค่าเริ่มต้นสำหรับคอลัมน์ 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 ถัดไปหากคุณทำงานภายใต้โครงการใด ๆ ที่คุณควรทราบเขตเวลาของลูกค้าและเลือกว่าคุณเป็นเขตลูกค้า ขั้นตอนนี้เป็นสิ่งจำเป็น