MySQL ค่าวันที่และเวลาไม่ถูกต้อง: '0000-00-00 00:00:00'


155

ฉันเพิ่งได้รับโครงการเก่าที่สร้างขึ้นเมื่อ 10 ปีก่อน มันใช้ MySQL 5.1

เหนือสิ่งอื่นใดฉันต้องเปลี่ยนชุดอักขระเริ่มต้นจาก latin1 เป็น utf8

ตัวอย่างเช่นฉันมีตารางเช่นนี้

  CREATE TABLE `users` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `first_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
    `last_name` varchar(45) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
    `username` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
    `email` varchar(127) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
    `pass` varchar(20) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL,
    `active` char(1) CHARACTER SET latin1 COLLATE latin1_general_ci NOT NULL DEFAULT 'Y',
    `created` datetime NOT NULL,
    `last_login` datetime DEFAULT NULL,
    `author` varchar(1) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT 'N',
    `locked_at` datetime DEFAULT NULL,
    `created_at` datetime DEFAULT NULL,
    `updated_at` datetime DEFAULT NULL,
    `ripple_token` varchar(36) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
    `ripple_token_expires` datetime DEFAULT '2014-10-31 08:03:55',
    `authentication_token` varchar(255) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `index_users_on_reset_password_token` (`reset_password_token`),
    UNIQUE KEY `index_users_on_confirmation_token` (`confirmation_token`),
    UNIQUE KEY `index_users_on_unlock_token` (`unlock_token`),
    KEY `users_active` (`active`),
    KEY `users_username` (`username`),
    KEY `index_users_on_email` (`email`)
  ) ENGINE=InnoDB AUTO_INCREMENT=1677 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC

ฉันตั้งค่า Mac ของตัวเองเพื่อทำงานนี้ โดยไม่ต้องคิดมากเกี่ยวกับเรื่องนี้ฉันรัน "brew ติดตั้ง mysql" ซึ่งติดตั้ง MySQL 5.7 ดังนั้นฉันมีข้อขัดแย้งของเวอร์ชัน

ฉันดาวน์โหลดสำเนาของฐานข้อมูลนี้และนำเข้า

หากฉันพยายามเรียกใช้แบบสอบถามเช่นนี้:

  ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci    NOT NULL  

ฉันได้รับข้อผิดพลาดนี้:

  ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1

ฉันคิดว่าฉันสามารถแก้ไขได้ด้วย:

  ALTER TABLE users MODIFY created datetime  NULL DEFAULT '1970-01-01 00:00:00';
  Query OK, 0 rows affected (0.06 sec)
  Records: 0  Duplicates: 0  Warnings: 0

แต่ฉันได้รับ:

  ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci    NOT NULL ;
  ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1

ฉันต้องอัพเดตทุกค่าหรือไม่?

คำตอบ:


12

ข้อเสนอแนะของฉันหากเป็นกรณีที่ตารางว่างเปล่าหรือไม่ใหญ่มากคือการส่งออกคำสั่งสร้างเป็นไฟล์. sql ให้เขียนข้อความใหม่ตามที่คุณต้องการ ทำเช่นเดียวกันหากคุณมีข้อมูลที่มีอยู่เช่นคำสั่งส่งออกแทรก (ฉันขอแนะนำให้ทำสิ่งนี้ในไฟล์แยกต่างหากเป็นคำสั่งสร้าง) ในที่สุดให้วางตารางและดำเนินการคำสั่งสร้างคำสั่งก่อนแล้วจึงแทรก

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


Lucia Pasarin ฉันชอบความคิดของคุณมาก แต่ข้อมูลจะไม่ถูกตัดทอนหรือ ข้อมูล UTF8 บางตัวใช้ไบต์มากกว่าละติน 1 หรือไม่ หากก่อนหน้านี้บางสิ่งบางอย่างพอดีใน varchar 255 บางทีตอนนี้มันจะไม่เป็นเช่นนั้น? ฉันควรเปลี่ยน varchars เป็นฟิลด์ "text" ทั้งหมดหรือไม่
lorm

ใช่คุณถูก. ที่อาจเกิดขึ้นเนื่องจาก latin1 ใช้ 1 ไบต์ต่อถ่านในขณะที่ utf8 ใช้ที่มากที่สุด 4 ไบต์ต่อถ่าน (ขึ้นอยู่กับรุ่นของ MySQL และชนิดของ utf8 dev.mysql.com/doc/refman/5.5/th/charset-unicode -utf8.html ) ดังนั้นคุณไม่จำเป็นต้องพิมพ์ TEXT ฉันจะสมมติว่า x4 ขนาดที่มีอยู่ก่อนหน้านี้ควรใช้งานได้
Lucia Pasarin

นี่เป็นฐานข้อมูลเทียบเท่ากับการฟอร์แมตฮาร์ดไดรฟ์ของคุณเมื่อคุณต้องการลบไฟล์ มันปลอดภัยที่จะพูดว่าวิธีนี้ไม่เป็นที่ยอมรับในสภาพแวดล้อมการผลิต
Brandon

198

ฉันไม่สามารถทำสิ่งนี้ได้:

UPDATE users SET created = NULL WHERE created = '0000-00-00 00:00:00'

(บน MySQL 5.7.13)

ฉันยังคงได้รับIncorrect datetime value: '0000-00-00 00:00:00'ข้อผิดพลาด

SELECT * FROM users WHERE created = '0000-00-00 00:00:00'แปลกนี้ทำงาน: ฉันไม่รู้ว่าทำไมอดีตล้มเหลวและใช้งานได้หลัง ... อาจเป็นข้อผิดพลาดของ MySQL หรือไม่

ไม่ว่าในกรณีใดแบบสอบถามแบบ UPDATE นี้จะทำงาน:

UPDATE users SET created = NULL WHERE CAST(created AS CHAR(20)) = '0000-00-00 00:00:00'

13
ผมมีปัญหาเหมือนกัน แต่การตั้งค่าส่วนสุดท้ายที่จะเพียงแค่ 0 คงที่สำหรับฉันเช่นนี้UPDATE users SET created = NULL WHERE created = '0'
ไบรอัน Leishman

SELECT * จากentityWHERE createdAt = "0000-00-00 00:00:00" ทำงานได้ดี แต่การอัปเดตล้มเหลว! ผมมีปัญหาเหมือนกัน. แก้ไขด้วยโซลูชันของ @obe CAST (สร้างเป็น CHAR (20)) ... ฉันคิดว่ามันเป็นข้อผิดพลาด
Chrysweel

44
สำหรับฉันมันใช้งานได้เหมือนUPDATE users SET created = NULL WHERE created=0(ไม่มี 'ประมาณศูนย์)
KIR

1
สำหรับการแทนที่วันที่ "0000-00-00" เท่านั้นโดยไม่มีการประทับเวลาฉันใช้ CHAR (11)
D.Tate

1
นั่นคืออัจฉริยะบริสุทธิ์ ทำไมนี่ไม่ใช่คำตอบที่ยอมรับ? สำหรับวันที่เท่านั้นไม่มีการประทับเวลาค่าต่ำสุดคือ 1000-01-01 พิจารณาใช้สิ่งนี้เป็นค่าเริ่มต้นสำหรับแอตทริบิวต์วันที่ที่คุณตั้งใจปล่อยว่างไว้หรือด้วยค่า 0000-00-00
Arvanitis Christos

155

การเปลี่ยนค่าเริ่มต้นสำหรับคอลัมน์ด้วยALTER TABLEคำสั่งเช่น

 ALTER TABLE users MODIFY created datetime  NULL DEFAULT '1970-01-02'

... ไม่เปลี่ยนค่าใด ๆ ที่เก็บไว้แล้ว ค่า "เริ่มต้น" นำไปใช้กับแถวที่ถูกแทรกและไม่มีการกำหนดค่าสำหรับคอลัมน์


สำหรับสาเหตุที่คุณพบข้อผิดพลาดอาจเป็นไปได้ว่าการsql_modeตั้งค่าสำหรับเซสชันของคุณมีNO_ZERO_DATEการตั้งค่าสำหรับเซสชันของคุณมี

อ้างอิง: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date

เมื่อคุณทำ "นำเข้า" คำสั่ง SQL ที่แทรกลงในตารางนั้นจะถูกเรียกใช้ในเซสชันที่อนุญาตสำหรับวันที่เป็นศูนย์

หากต้องการดูการตั้งค่า sql_mode:

SHOW VARIABLES LIKE 'sql_mode' ;

-หรือ-

SELECT @@sql_mode ;

เท่าที่จะ "แก้ไข" ปัญหาปัจจุบันเพื่อให้ข้อผิดพลาดจะไม่ถูกโยนเมื่อคุณเรียกใช้ALTER TABLEคำสั่ง

หลายตัวเลือก:

1) การเปลี่ยนแปลงsql_modeที่จะอนุญาตให้เป็นศูนย์วันโดยการลบและNO_ZERO_DATE NO_ZERO_IN_DATEการเปลี่ยนแปลงสามารถนำไปใช้ในไฟล์ my.cnf ดังนั้นหลังจากรีสตาร์ทเซิร์ฟเวอร์ MySQL sql_modeตัวแปรจะเริ่มต้นการตั้งค่าใน my.cnf

สำหรับการเปลี่ยนแปลงชั่วคราวเราสามารถแก้ไขการตั้งค่าด้วยเซสชันเดียวโดยไม่ต้องการการเปลี่ยนแปลงระดับโลก

-- save current setting of sql_mode
SET @old_sql_mode := @@sql_mode ;

-- derive a new value by removing NO_ZERO_DATE and NO_ZERO_IN_DATE
SET @new_sql_mode := @old_sql_mode ;
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_DATE,'  ,','));
SET @new_sql_mode := TRIM(BOTH ',' FROM REPLACE(CONCAT(',',@new_sql_mode,','),',NO_ZERO_IN_DATE,',','));
SET @@sql_mode := @new_sql_mode ;

-- perform the operation that errors due to "zero dates"

-- when we are done with required operations, we can revert back
-- to the original sql_mode setting, from the value we saved
SET @@sql_mode := @old_sql_mode ;

2) เปลี่ยน createdคอลัมน์เพื่ออนุญาตให้มีค่า NULL และอัปเดตแถวที่มีอยู่เพื่อเปลี่ยนวันที่เป็นศูนย์ให้เป็นค่า Null

3) อัปเดตแถวที่มีอยู่เพื่อเปลี่ยนวันที่เป็นศูนย์ให้เป็นวันที่ที่ถูกต้อง


เราไม่จำเป็นต้องเรียกใช้แต่ละคำสั่งเพื่ออัปเดตแต่ละแถว เราสามารถอัปเดตทุกแถวในคราวเดียวได้ (สมมติว่าเป็นตารางที่มีขนาดพอเหมาะสำหรับตารางที่ใหญ่กว่าเพื่อหลีกเลี่ยงการย้อนกลับที่ไม่เป็นอันตราย / ยกเลิกการสร้าง

ในคำถามAUTO_INCREMENTค่าที่แสดงสำหรับคำจำกัดความของตารางทำให้เรามั่นใจว่าจำนวนแถวไม่มากเกินไป

หากเราเปลี่ยนcreatedคอลัมน์เพื่ออนุญาตNULLค่าเราสามารถทำสิ่งนี้:

UPDATE  `users` SET `created` = NULL WHERE `created` = '0000-00-00 00:00:00'

หรือเราสามารถตั้งค่าให้เป็นวันที่ที่ถูกต้องเช่น 2 มกราคม 1970

UPDATE  `users` SET `created` = '1970-01-02' WHERE `created` = '0000-00-00 00:00:00'

(โปรดทราบว่าค่าวันที่และเวลาเที่ยงคืนของวันที่ 1 มกราคม 1970 ( '1970-01-01 00:00:00') คือ "zero date" ซึ่งจะได้รับการประเมินว่าเป็น'0000-00-00 00:00:00'


3
ใช่มันใช้งานได้สำหรับฉัน ฉันค้นหาโหมด sql ในไฟล์ my.ini และลบ NO_ZERO_IN_DATE และ NO_ZERO_DATE จากนั้นเริ่มบริการใหม่ ขอบคุณ spencer7593!
mili


เมื่อฉัน # # 2 "เปลี่ยนคอลัมน์ที่สร้างขึ้นเพื่อให้ค่า NULL" มันจะไม่ให้ฉันเพราะค่าคอลัมน์ยังคงเกิดข้อผิดพลาด ค่อนข้างติดอยู่
Mike Weir

1
@MikeWeir: สันนิษฐานว่า " ไม่ให้ฉัน " หมายความว่ามีการส่งคืนข้อผิดพลาดเมื่อคำสั่ง SQL ถูกเรียกใช้ sql_modeนั่นน่าจะเกิดจากการตั้งค่าของ MySQL รุ่นที่ใหม่กว่ามีการตั้งค่าเริ่มต้นsql_modeที่เข้มงวดกว่ารุ่นก่อนหน้า อ้างอิงสำหรับ 8.0 ที่นี่: dev.mysql.com/doc/refman/8.0/en/sql-mode.html เห็นNO_ZERO_DATE, ALLOW_INVALID_DATE, et al ทราบว่าบางส่วนจะรวมอยู่ในโหมดเช่นเคร่งครัดSTRICT_TRANS_TABLES, STRICT_ALL_TABLESและโหมดคำสั่งผสมอื่น ๆ หากต้องการแก้ไขข้อ จำกัด ให้แก้ไข sql_mode ชั่วคราวสำหรับเซสชันชั่วคราว
spencer7593

@ spencer7593 แน่นอน ฉันไม่รู้สึกว่าตัวเลือกนั้นดีที่สุด ฉันได้รับคำแนะนำของคุณในการตั้งค่าวันที่ที่เก่ามาก (1970) และระบบของฉันจะเพิกเฉย ขอบคุณสำหรับรายละเอียดทั้งหมดของคุณ
Mike Weir

67

ฉันได้รับการแก้ไขโดยทำสิ่งนี้ก่อนที่จะค้นหา

SET SQL_MODE='ALLOW_INVALID_DATES';

นี่เป็นคำตอบเดียว ใช้เป็น: --init-command = 'SET SESSION FOREIGN_KEY_CHECKS = 0; SET SQL_MODE =' ALLOW_INVALID_DATES '
Konchog

ขอบคุณมาก. ไม่สามารถอธิบายได้ว่าปัญหานี้เป็นความเจ็บปวดของฉันเพียงใด
Dieter Gribnitz

42

อ้างอิงจากMySQL 5.7 คู่มืออ้างอิง :

โหมด SQL เริ่มต้นใน MySQL 5.7 รวมถึงโหมดเหล่านี้: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER และ NOENGTHITUTION

เนื่องจาก0000-00-00 00:00:00ไม่ใช่DATETIMEค่าที่ถูกต้องฐานข้อมูลของคุณจึงขาด นั่นคือเหตุผลที่ MySQL 5.7 ซึ่งมาพร้อมกับNO_ZERO_DATEโหมดเปิดใช้งานโดยค่าเริ่มต้นจะแสดงข้อผิดพลาดเมื่อคุณพยายามทำการเขียน

คุณสามารถแก้ไขตารางของคุณเพื่อปรับปรุงค่าที่ไม่ถูกต้องทั้งหมดให้เป็นค่าที่ถูกต้องอื่น ๆ เช่นNULL:

UPDATE users SET created = NULL WHERE created < '0000-01-01 00:00:00'

นอกจากนี้เพื่อหลีกเลี่ยงปัญหานี้ผมขอแนะนำให้คุณตั้งเวลาปัจจุบันเป็นค่าเริ่มต้นสำหรับคุณเหมือนทุ่งนาเพื่อให้พวกเขาได้รับเต็มโดยอัตโนมัติcreated INSERTแค่ทำ:

ALTER TABLE users
ALTER created SET DEFAULT CURRENT_TIMESTAMP

8
SET sql_mode = 'NO_ZERO_DATE';
UPDATE `news` SET `d_stop`='2038-01-01 00:00:00' WHERE `d_stop`='0000-00-00 00:00:00'

4
คำตอบนี้จะได้รับการปรับปรุงด้วยการอภิปรายว่าทำไมจึงแก้ปัญหานี้
KevinO

สิ่งนี้จะส่งผลกระทบต่อการจัดเก็บข้อมูลวันที่และเวลาหรือไม่ หรือทำให้เกิดปัญหาใด ๆ
Ask Bytes

8

นี่คือสิ่งที่ทางออกของฉันPhpMyAdmin / Fedora 29 / MySQL 8.0 (ตัวอย่าง):

set sql_mode='SOMETHING'; ไม่ทำงานการเรียกคำสั่งสำเร็จ แต่ไม่มีอะไรเปลี่ยนแปลง

set GLOBAL sql_mode='SOMETHING'; เปลี่ยนการกำหนดค่าส่วนกลางเปลี่ยนแปลงถาวร

set SESSION sql_mode='SOMETHING'; เปลี่ยนการกำหนดค่าเซสชันตัวแปร SESSION มีผลกับไคลเอ็นต์ปัจจุบันเท่านั้น

https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html

ดังนั้นฉันทำสิ่งนี้:

  • รับ SQL_MODE: SHOW VARIABLES LIKE 'sql_mode';
  • ผลลัพธ์ : ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
  • ลบออกจากผลลัพธ์: NO_ZERO_IN_DATE,NO_ZERO_DATE
  • ตั้งค่าใหม่: set GLOBAL SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

คุณสามารถลบหรือเพิ่มโหมดอื่นในวิธีเดียวกัน

สิ่งนี้จะเป็นประโยชน์ในการเปลี่ยนโกลบอลสำหรับการใช้และการทดสอบเฟรมเวิร์กหรือ sql_mode ต้องถูกระบุในแต่ละไฟล์

ดัดแปลงมาจากคำถามถามที่นี่: วิธีทำ i-disable-mysql-เข้มงวด-mode

ตัวอย่าง: ติดตั้งเนื้อหา Joomla 4.0-alpha ล่าสุด

แก้ไข: ใน PhpMyadmin หากคุณมีการควบคุมเซิร์ฟเวอร์คุณสามารถเปลี่ยนsql_mode(และพารามิเตอร์อื่น ๆ ทั้งหมด) ได้โดยตรงในPlus > Variables > sql_mode


5

คุณสามารถเปลี่ยนประเภทของการสร้างเขตข้อมูลจากdatetimeการvarchar(255)แล้วคุณสามารถตั้งค่า (update) ระเบียนทั้งหมดที่มีค่าไป"0000-00-00 00:00:00"NULL

ตอนนี้คุณสามารถทำแบบสอบถามโดยไม่มีข้อผิดพลาด หลังจากที่คุณเสร็จแล้วคุณสามารถปรับเปลี่ยนประเภทของข้อมูลที่สร้างขึ้นdatetimeเพื่อ


4

ฉันมีข้อผิดพลาดนี้เช่นกันหลังจากอัปเกรด MySQL จาก 5.6 เป็น 5.7

ฉันคิดว่าทางออกที่ดีที่สุดสำหรับฉันคือการรวมโซลูชันบางอย่างที่นี่เข้าด้วยกันและสร้างบางสิ่งที่ทำงานร่วมกับอินพุตขั้นต่ำ

ฉันใช้ MyPHPAdmin เพื่อความง่ายในการส่งข้อความค้นหาผ่านอินเทอร์เฟซเพราะจากนั้นฉันสามารถตรวจสอบโครงสร้างและสิ่งต่าง ๆ ได้อย่างง่ายดาย คุณอาจใช้ ssh โดยตรงหรืออินเทอร์เฟซอื่น ๆ วิธีการควรจะคล้ายหรือเหมือนกันต่อไป

...

1

ก่อนอื่นให้ตรวจสอบข้อผิดพลาดที่เกิดขึ้นจริงเมื่อพยายามซ่อมแซม db:

joomla.jos_menu หมายเหตุ: คอลัมน์ TIME / TIMESTAMP / DATETIME ของรูปแบบเก่าได้รับการอัพเกรดเป็นรูปแบบใหม่

คำเตือน: ค่าวันที่และเวลาไม่ถูกต้อง: '0000-00-00 00:00:00' สำหรับคอลัมน์ 'checked_out_time' ที่แถว 1

ข้อผิดพลาด: ค่าเริ่มต้นไม่ถูกต้องสำหรับ 'checked_out_time'

สถานะ: การดำเนินการล้มเหลว

สิ่งนี้บอกคอลัมน์ที่มีการตรวจสอบแล้ว _out_time ในตาราง jos_menu จำเป็นต้องแก้ไขวันที่ไม่ดีทั้งหมดรวมถึงการเปลี่ยนแปลง "ค่าเริ่มต้น"

...

2

ฉันรันการสืบค้น SQL ตามข้อมูลในข้อความแสดงข้อผิดพลาด:

UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE checked_out_time = 0

หากคุณได้รับข้อผิดพลาดคุณสามารถใช้แบบสอบถามด้านล่างแทนที่ดูเหมือนว่าจะทำงานเสมอ:

UPDATE jos_menu SET checked_out_time = '1970-01-01 08:00:00' WHERE CAST(checked_out_time AS CHAR(20)) = '0000-00-00 00:00:00'

...

3

จากนั้นเมื่อทำเสร็จแล้วฉันจะเรียกใช้แบบสอบถาม SQL ชุดที่สอง:

ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT CURRENT_TIMESTAMP;

หรือในกรณีที่เป็นวันที่จะต้องมีค่า NULL

ALTER TABLE `jos_menu` CHANGE `checked_out_time` `checked_out_time` DATETIME NULL DEFAULT NULL;

...

ถ้าฉันใช้ฐานข้อมูลการซ่อมแซมตอนนี้ฉันจะได้รับ:

joomla.jos_menu ตกลง

...

ทำงานได้ดี :)


4

ตรวจสอบ

SELECT @@sql_mode;

หากคุณเห็นสิ่ง 'ZERO_DATE' อยู่ในนั้นให้ลอง

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_DATE',''));   
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'NO_ZERO_IN_DATE',''));   

ออกจากระบบและกลับมาที่ไคลเอ็นต์ของคุณอีกครั้ง (นี่แปลก) แล้วลองอีกครั้ง


3

ทำให้โหมด sql ไม่เข้มงวด

หากใช้ laravel ไปที่ฐานข้อมูล config-> ไปที่การตั้งค่า mysql และทำให้โหมดเข้มงวดเป็นเท็จ


ฉันสามารถทำสิ่งนี้ใน myphpadmin ได้หรือไม่
Don King

phpMyAdmin เป็นเพียงอินเทอร์เฟซสำหรับใช้เซิร์ฟเวอร์ mysql จริงมันไม่สำคัญว่าอินเทอร์เฟซใดที่คุณใช้คำสั่ง mysql จะไม่เปลี่ยนกับอินเทอร์เฟซ ลองใช้คำสั่งนี้ (set sql_mode = '';) หรือนี่ (set global sql_mode = '';) เพื่อปิด
Milind Chaudhary

1
ใช่ฉันพบทุกสิ่งที่จำเป็นในการปิดโหมดเข้มงวดคือการเพิ่ม sql_mode = (และไม่มีอะไรหลังจากนั้น) โดยด้านล่างของ my.cnf
Don King

3

ฉันมีปัญหาที่คล้ายกัน แต่ในกรณีของฉันบางบรรทัดมีค่าเป็นศูนย์

ดังนั้นก่อนอื่นฉันจะอัพเดทตาราง:

update `my_table`set modified = '1000-01-01 00:00:00' WHERE modified is null

แก้ไขปัญหาอย่างน้อยในกรณีของฉัน


2

ฉันยังได้รับ

SQLSTATE [22007]: รูปแบบวันที่และเวลาไม่ถูกต้อง: 1292 ค่าวันที่และเวลาไม่ถูกต้อง: '0000-00-00 00:00:00' สำหรับคอลัมน์

ข้อมูลผิดพลาด

แก้ไขสิ่งนี้โดยเปลี่ยน 0000-00-00 00:00:00 เป็น 1970-01-01 08:00:00

1970-01-01 08:00:00 unix timestamp คือ 0


1
ปัญหาคือ OP ไม่สามารถเปลี่ยนวันเนื่องจากข้อผิดพลาด ฉันเดาว่ามันเป็นข้อผิดพลาดจากNO_ZERO_DATE
GusDeCooL

2

ผมพบว่าวิธีการแก้ปัญหาที่https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-SQL-mode-in-MySQL ฉันมีสิ่งนี้:

mysql> show variables like 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                     |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.01 sec)

สังเกตเห็นNO_ZERO_IN_DATE,NO_ZERO_DATEในผลลัพธ์ข้างต้น ฉันลบมันโดยทำสิ่งนี้:

mysql> SET sql_mode = 'ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected, 1 warning (0.00 sec)

จากนั้นฉันก็มีสิ่งนี้:

mysql> show variables like 'sql_mode';
+---------------+--------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                        |
+---------------+--------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+--------------------------------------------------------------------------------------------------------------+
1 row in set, 1 warning (0.01 sec)

หลังจากทำเช่นนั้นฉันสามารถใช้งานได้ALTER TABLEสำเร็จและปรับเปลี่ยนตารางของฉัน


1

นี่คือสิ่งที่ฉันทำเพื่อแก้ไขปัญหาของฉัน ฉันทดสอบในท้องถิ่นMySQL 5.7 ubuntu 18.04

set global sql_mode="NO_ENGINE_SUBSTITUTION";

ก่อนที่จะรันการสืบค้นนี้ทั่วโลกฉันได้เพิ่มไฟล์ cnf ใน ไดเร็กทอรี/etc/mysql/conf.d ชื่อไฟล์ cnf คือmysql.cnfและรหัส

[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

จากนั้นฉันเริ่ม mysql ใหม่

sudo service mysql restart

หวังว่าสิ่งนี้จะช่วยให้ใครบางคน


วิธีนี้ใช้ได้ผลจนกว่าฉันจะรีสตาร์ทเซิร์ฟเวอร์ MySQL แม้หลังจากรีสตาร์ทค่าNO_ENGINE_SUBSTITUTIONอยู่ในคอลัมน์ทั้งหมดSELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;แต่ฉันยังคงได้รับข้อผิดพลาดสำหรับวันที่และเวลาที่ไม่ถูกต้อง0000-00-00 00:00:00จนกว่าฉันจะเรียกใช้คิวรีแรกอีกครั้งset global sql_mode="NO_ENGINE_SUBSTITUTION";แนวคิดใดบ้าง
Smamatti

วิธีการแก้ปัญหาในกรณีของฉันคือการลบNO_ZERO_IN_DATE,NO_ZERO_DATEในรุ่นของสาย my.ini sql_modeกำหนด
Smamatti

1

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

  1. เลือก ID ของคอลัมน์ที่เสีย

    select id from table where BadColumn='0000-00-00 00:00:00'

  2. รวบรวม ID ลงในสตริงที่คั่นด้วยจุลภาค ตัวอย่าง: 1, 22, 33. ฉันใช้ wrapper ภายนอกสำหรับสิ่งนี้ (สคริปต์ Perl) เพื่อคายมันออกมาอย่างรวดเร็ว

  3. ใช้รายการ ID ของคุณเพื่ออัปเดตคอลัมน์เก่าด้วยวันที่ที่ถูกต้อง (1971 ถึง 2038)

    update table set BadColumn='2000-01-01 00:00:00' where id in (1, 22, 33)



1

แทน

UPDATE your_table SET your_column = new_valid_value where your_column = '0000-00-00 00:00:00';

ใช้

UPDATE your_table SET your_column = new_valid_value where your_column = 0;

0

หากคุณกำลังป้อนข้อมูลด้วยตนเองคุณอาจพิจารณาลบค่าและศูนย์ใน TIMESTAMP (6) .000000 เพื่อให้เป็น TIMESTAMP มันใช้ได้ดีกับฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.