MySQL Giá trị thời gian không chính xác: '0000-00-00 00:00:00'


155

Gần đây tôi đã tiếp quản một dự án cũ đã được tạo ra cách đây 10 năm. Nó sử dụng MySQL 5.1.

Trong số những thứ khác, tôi cần thay đổi bộ ký tự mặc định từ latin1 thành utf8.

Ví dụ, tôi có các bảng như thế này:

  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

Tôi thiết lập máy Mac của riêng tôi để làm việc này. Không cần suy nghĩ quá nhiều về nó, tôi đã chạy "brew install mysql" đã cài đặt MySQL 5.7. Vì vậy, tôi có một số xung đột phiên bản.

Tôi đã tải xuống một bản sao của cơ sở dữ liệu này và nhập nó.

Nếu tôi cố chạy một truy vấn như thế này:

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

Tôi nhận được lỗi này:

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

Tôi nghĩ rằng tôi có thể khắc phục điều này với:

  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

nhưng tôi nhận được:

  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

Tôi có phải cập nhật mọi giá trị không?

Câu trả lời:


12

Đề nghị của tôi nếu đó là trường hợp bảng trống hoặc không rất lớn là xuất các câu lệnh tạo dưới dạng tệp .sql, viết lại chúng theo ý muốn. Cũng làm tương tự nếu bạn có bất kỳ dữ liệu hiện có nào, tức là xuất các câu lệnh chèn (tôi khuyên bạn nên làm điều này trong một tệp riêng biệt như các câu lệnh tạo). Cuối cùng, thả bảng và thực hiện câu lệnh tạo đầu tiên và sau đó chèn.

Bạn có thể sử dụng cho mysqldumplệnh đó, bao gồm trong cài đặt MySQL của bạn hoặc bạn cũng có thể cài đặt MySQL Workbench, đây là một công cụ đồ họa miễn phí bao gồm tùy chọn này theo cách rất tùy biến mà không cần phải tìm các tùy chọn lệnh cụ thể.


Lucia Pasarin, tôi rất thích ý tưởng của bạn, nhưng liệu dữ liệu có bị cắt ngắn không? Có một số dữ liệu UTF8 chiếm nhiều byte hơn latin1 không? Nếu một cái gì đó trước đây phù hợp với varchar 255, có lẽ bây giờ nó sẽ không? Tôi có nên, có lẽ, thay đổi tất cả các varchars thành các trường "văn bản"?
lorm

Vâng, bạn đúng. Điều đó có thể xảy ra vì latin1 sử dụng 1 byte mỗi char, trong khi utf8 sử dụng tối đa 4 byte mỗi char (tùy thuộc vào phiên bản của MySQL và loại utf8 dev.mysql.com/doc/refman/5.5/en/charset-unicode -utf8.html ). Do đó, bạn không nhất thiết cần loại văn bản. Tôi sẽ giả sử rằng x4 kích thước hiện tại của bạn sẽ hoạt động.
Lucia Pasarin

Đây là cơ sở dữ liệu tương đương với việc định dạng lại ổ cứng của bạn khi bạn muốn xóa một tập tin. Thật an toàn khi nói giải pháp này không được chấp nhận trong môi trường sản xuất.
Brandon

198

Tôi đã không thể làm điều này:

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

(trên MySQL 5.7.13).

Tôi tiếp tục nhận được Incorrect datetime value: '0000-00-00 00:00:00'lỗi.

Kỳ lạ thay, điều này đã làm việc : SELECT * FROM users WHERE created = '0000-00-00 00:00:00'. Tôi không biết tại sao cái trước thất bại và cái sau hoạt động ... có thể là lỗi của MySQL?

Trong mọi trường hợp, truy vấn CẬP NHẬT này hoạt động:

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

13
Tôi có cùng một vấn đề, nhưng đặt phần cuối cùng thành 0 đã sửa nó cho tôi như thế này:UPDATE users SET created = NULL WHERE created = '0'
Brian Leishman

CHỌN * TỪ entityWHERE createdAt = "0000-00-00 00:00:00" hoạt động tốt, nhưng không cập nhật! Tôi đã từng gặp vấn đề tương tự. Khắc phục sự cố bằng giải pháp @obe CAST (đã tạo AS CHAR (20)) ... Tôi nghĩ rằng đó là một lỗi.
Chrysweel

44
Đối với tôi nó hoạt động như thế nào UPDATE users SET created = NULL WHERE created=0(không có 'khoảng không)
KIR

1
Để chỉ thay thế ngày "0000-00-00" mà không có dấu thời gian, tôi đã sử dụng CHAR (11)
D.Tate

1
Đó là thiên tài thuần túy. Tại sao đây không phải là câu trả lời được chấp nhận? Đối với ngày chỉ không có dấu thời gian, giá trị tối thiểu là 1000-01-01. Cân nhắc sử dụng giá trị này làm giá trị mặc định cho mọi thuộc tính ngày bạn định để trống hoặc với giá trị 0000-00-00.
Arvanitis Christos

155

Thay đổi giá trị mặc định cho một cột bằng một ALTER TABLEcâu lệnh, vd

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

... không thay đổi bất kỳ giá trị nào đã được lưu trữ. Giá trị "mặc định" áp dụng cho các hàng được chèn và giá trị này không được cung cấp cho cột.


Về lý do tại sao bạn gặp phải lỗi, có thể sql_modecài đặt cho phiên của bạn bao gồm NO_ZERO_DATE.

Tham khảo: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date

Khi bạn thực hiện "nhập", các câu lệnh SQL đã thực hiện INSERT vào bảng đó sẽ được chạy trong một phiên cho phép không có ngày.

Để xem cài đặt sql_mode:

SHOW VARIABLES LIKE 'sql_mode' ;

-hoặc là-

SELECT @@sql_mode ;

Theo như cách "khắc phục" sự cố hiện tại, để lỗi sẽ không bị ném khi bạn chạy ALTER TABLEcâu lệnh.

Một vài lựa chọn:

1) thay đổi sql_modeđể cho phép ngày không, bằng cách loại bỏ NO_ZERO_DATENO_ZERO_IN_DATE. Thay đổi có thể được áp dụng trong tệp my.cnf, vì vậy sau khi khởi động lại Máy chủ MySQL, sql_modebiến sẽ được khởi tạo cho cài đặt trong my.cnf.

Để thay đổi tạm thời, chúng tôi có thể sửa đổi cài đặt với một phiên duy nhất mà không yêu cầu thay đổi toàn cầu.

-- 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) thay đổi createdcột để cho phép các giá trị NULL và cập nhật các hàng hiện có để thay đổi ngày không thành giá trị null

3) cập nhật các hàng hiện có để thay đổi ngày không thành ngày hợp lệ


Chúng tôi không cần chạy các câu lệnh riêng lẻ để cập nhật từng hàng. Chúng tôi có thể cập nhật tất cả các hàng trong một cú trượt (giả sử đó là một bảng có kích thước hợp lý. Đối với một bảng lớn hơn, để tránh tạo ra rollback / hoàn tác khiêm tốn, chúng tôi có thể thực hiện thao tác trong các khối có kích thước hợp lý.)

Trong câu hỏi, AUTO_INCREMENTgiá trị hiển thị cho định nghĩa bảng đảm bảo với chúng ta rằng số lượng hàng không quá nhiều.

Nếu chúng tôi đã thay đổi createdcột để cho phép các NULLgiá trị, chúng tôi có thể làm một cái gì đó như thế này:

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

Hoặc, chúng ta có thể đặt những ngày đó thành một ngày hợp lệ, ví dụ: ngày 2 tháng 1 năm 1970

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

(Lưu ý rằng giá trị thời gian của nửa đêm ngày 1 tháng 1 năm 1970 ( '1970-01-01 00:00:00') "ngày không". Điều đó sẽ được đánh giá là'0000-00-00 00:00:00'


3
vâng, điều này làm việc cho tôi Tôi đã tìm kiếm chế độ sql trong tệp my.ini và xóa NO_ZERO_IN_DATE và NO_ZERO_DATE. sau đó khởi động lại dịch vụ. cảm ơn bạn Spencer7593!
mili


Khi tôi thực hiện # 2 "thay đổi cột đã tạo để cho phép các giá trị NULL", điều đó sẽ không cho phép tôi vì các giá trị cột vẫn tạo ra lỗi. Khá bế tắc.
Mike Weir

1
@Mike Weir: có lẽ " sẽ không cho phép tôi " có nghĩa là một lỗi được trả về khi một câu lệnh SQL được thực thi. Đó có thể là do các thiết lập của sql_mode. Các phiên bản gần đây hơn của MySQL có các cài đặt mặc định sql_modenghiêm ngặt hơn các phiên bản trước đó. Tài liệu tham khảo cho 8,0 ở đây: dev.mysql.com/doc/refman/8.0/en/sql-mode.html see NO_ZERO_DATE, ALLOW_INVALID_DATE, et al. lưu ý rằng một số được bao gồm trong chế độ STRICT STRICT_TRANS_TABLES, ví dụ STRICT_ALL_TABLESvà các chế độ kết hợp khác. Để khắc phục các hạn chế, tạm thời sửa đổi sql_mode cho phiên,
spencer7593

@ spencer7593 cho chắc chắn. Tôi không cảm thấy lựa chọn đó là tốt nhất. Tôi đã lấy lời khuyên của bạn về việc đặt giá trị ngày rất cũ (1970) và hệ thống của tôi sẽ bỏ qua nó. Cảm ơn tất cả các chi tiết của bạn.
Mike Weir

67

Tôi đã sửa nó bằng cách làm điều này trước khi truy vấn

SET SQL_MODE='ALLOW_INVALID_DATES';

Đây là câu trả lời duy nhất. Được sử dụng như: --init-lệnh = 'SET SESSION FOREIGN_KEY_CHECKS = 0; SET SQL_MODE =' ALLOW_INVALID_DATE '
Konchog

Cảm ơn bạn rất nhiều. Không thể giải thích nỗi đau này là gì đối với tôi.
Dieter Gribnitz

42

Theo tài liệu tham khảo MySQL 5.7 :

Chế độ SQL mặc định trong MySQL 5.7 bao gồm các chế độ sau: ONLY_FULL_GROUP_BY, STRICT_TRANS_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO, NO_AUTO_CREATE_USER, NO_

0000-00-00 00:00:00không phải là một giá DATETIMEtrị hợp lệ , cơ sở dữ liệu của bạn bị hỏng. Đó là lý do tại sao MySQL 5.7 - đi kèm với NO_ZERO_DATEchế độ được bật theo mặc định - sẽ xuất hiện lỗi khi bạn cố thực hiện thao tác ghi.

Bạn có thể sửa bảng của mình cập nhật tất cả các giá trị không hợp lệ thành bất kỳ giá trị hợp lệ nào khác, như NULL:

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

Ngoài ra, để tránh sự cố này, tôi khuyên bạn luôn đặt thời gian hiện tại làm giá trị mặc định cho các createdtrường giống như của bạn để chúng được tự động điền vào INSERT. Cứ làm đi:

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
Câu trả lời này sẽ được cải thiện với thảo luận về lý do tại sao điều này giải quyết vấn đề.
KevinO

điều này có ảnh hưởng đến việc lưu trữ datetime không? hoặc gây ra bất kỳ vấn đề nào
Hỏi Byte

8

Đây là giải pháp của tôi PhpMyAdmin / Fedora 29 / MySQL 8.0 (ví dụ):

set sql_mode='SOMETHING'; không hoạt động , lệnh gọi thành công nhưng không có gì thay đổi.

set GLOBAL sql_mode='SOMETHING'; thay đổi cấu hình toàn cầu thay đổi vĩnh viễn.

set SESSION sql_mode='SOMETHING'; thay đổi cấu hình phiên Biến SESSION chỉ ảnh hưởng đến máy khách hiện tại.

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

Vì vậy, tôi làm điều này:

  • Nhận SQL_MODE: SHOW VARIABLES LIKE 'sql_mode';
  • Kết quả : ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
  • Xóa kết quả: NO_ZERO_IN_DATE,NO_ZERO_DATE
  • Đặt cấu hình mới: set GLOBAL SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

Bạn có thể loại bỏ hoặc thêm chế độ khác theo cùng một cách.

Điều này hữu ích để thay đổi toàn cầu để sử dụng và kiểm tra các khung hoặc sql_mode phải được chỉ định trong mỗi tệp hoặc một loạt các truy vấn.

Chuyển thể từ một câu hỏi tại đây: how-can-i-vô hiệu hóa-mysql -rict-mode

Ví dụ: cài đặt nội dung Joomla 4.0-alpha mới nhất.

Chỉnh sửa: Trong PhpMyadmin, nếu bạn có quyền kiểm soát máy chủ, bạn có thể thay đổi sql_modetrực tiếp (và tất cả các tham số khác) trongPlus > Variables > sql_mode


5

Bạn có thể thay đổi loại trường đã tạo từ datetimethành varchar(255), sau đó bạn có thể đặt (cập nhật) tất cả các bản ghi có giá trị "0000-00-00 00:00:00"thànhNULL .

Bây giờ, bạn có thể thực hiện các truy vấn của bạn mà không có lỗi. Sau khi bạn đã hoàn thành, bạn có thể thay đổi các loại lĩnh vực tạo để datetime.


4

Tôi cũng gặp lỗi này sau khi nâng cấp MySQL từ 5.6 lên 5.7

Tôi đã tìm ra rằng giải pháp tốt nhất cho tôi là kết hợp một số giải pháp ở đây và làm cho một cái gì đó của nó hoạt động với mức tối thiểu của đầu vào.

Tôi sử dụng MyPHPAdmin vì đơn giản gửi các truy vấn thông qua giao diện vì sau đó tôi có thể kiểm tra cấu trúc và tất cả những điều đó một cách dễ dàng. Bạn có thể sử dụng ssh trực tiếp hoặc một số giao diện khác. Phương pháp nên tương tự hoặc giống nhau.

...

1.

Trước tiên hãy kiểm tra lỗi thực tế khi cố gắng sửa chữa db:

j Joomla.jos_menu Lưu ý: Các cột TIME / TIMESTAMP / DATETIME có định dạng cũ đã được nâng cấp lên định dạng mới.

Cảnh báo: Giá trị thời gian không chính xác: '0000-00-00 00:00:00' cho cột 'đã kiểm tra_time' ở hàng 1

Lỗi: Giá trị mặc định không hợp lệ cho 'đã kiểm tra_time'

trạng thái: Hoạt động không thành công

Điều này cho tôi biết cột đã được kiểm tra_time trong bảng jos_menu cần phải sửa tất cả các ngày xấu cũng như "mặc định" đã thay đổi.

...

2.

Tôi chạy truy vấn SQL dựa trên thông tin trong thông báo lỗi:

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

Nếu bạn gặp lỗi, bạn có thể sử dụng truy vấn bên dưới thay vào đó dường như luôn hoạt động:

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.

Sau đó, khi đã xong, tôi chạy truy vấn SQL thứ hai:

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

Hoặc trong trường hợp đó là một ngày phải là NULL

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

...

Nếu tôi chạy cơ sở dữ liệu sửa chữa bây giờ tôi nhận được:

j Joomla.jos_menu OK

...

Hoạt động tốt :)


4

Kiểm tra

SELECT @@sql_mode;

nếu bạn thấy nội dung 'ZERO_DATE' trong đó, hãy thử

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

Đăng xuất và đăng nhập lại cho khách hàng của bạn (điều này thật lạ) và thử lại


3

Làm cho chế độ sql không nghiêm ngặt

Nếu sử dụng laravel, hãy truy cập config-> cơ sở dữ liệu, chuyển đến cài đặt mysql và đặt chế độ nghiêm ngặt thành false


Tôi có thể làm điều này trong myphpadmin không?
Don King

phpMyAdmin chỉ là một giao diện để sử dụng máy chủ mysql thực tế, không quan trọng bạn đang sử dụng giao diện nào trong các lệnh mysql sẽ không thay đổi với giao diện. Hãy thử lệnh này (đặt sql_mode = '';) hoặc điều này (đặt toàn cầu sql_mode = '';) để tắt.
Milind Chaudhary

1
vâng tôi thấy tất cả những gì cần thiết để tắt chế độ nghiêm ngặt là thêm sql_mode = (và không có gì sau nó), ở dưới cùng của my.cnf
Don King

3

Tôi đã có một vấn đề tương tự nhưng trong trường hợp của tôi, một số dòng có giá trị NULL.

vì vậy trước tiên tôi cập nhật bảng:

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

vấn đề được giải quyết, ít nhất là trong trường hợp của tôi.


2

Tôi cũng có

SQLSTATE [22007]: Định dạng thời gian không hợp lệ: 1292 Giá trị thời gian không chính xác: '0000-00-00 00:00:00' cho cột

thông tin lỗi

Khắc phục sự cố này bằng cách thay đổi 0000-00-00 00:00:00 thành 1970-01-01 08:00:00

1970-01-01 08:00:00 dấu thời gian unix là 0


1
vấn đề là OP không thể thay đổi ngày vì lỗi. Tôi đoán đó là lỗi từNO_ZERO_DATE
GusDeCooL

2

Tôi đã tìm thấy giải pháp tại https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-Query-mode-in-MySQL . Tôi đã có điều này:

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)

Lưu ý các NO_ZERO_IN_DATE,NO_ZERO_DATEkết quả trên. Tôi đã loại bỏ điều đó bằng cách làm điều này:

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)

Sau đó, tôi đã có điều này:

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)

Sau khi làm điều đó, tôi có thể sử dụng ALTER TABLEthành công và thay đổi các bảng của tôi.


1

Đây là những gì tôi đã làm để giải quyết vấn đề của tôi. Tôi đã thử nghiệm trong MySQL 5.7 cục bộ 18.04.

set global sql_mode="NO_ENGINE_SUBSTITUTION";

Trước khi chạy truy vấn này trên toàn cầu, tôi đã thêm một tệp cnf trong thư mục /etc/mysql/conf.d . Tên tệp cnf là mysql.cnf và mã

[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

Sau đó tôi khởi động lại mysql

sudo service mysql restart

Hy vọng điều này có thể giúp đỡ một ai đó.


Giải pháp này hoạt động cho đến khi tôi khởi động lại máy chủ MySQL. Ngay cả sau khi khởi động lại, giá trị NO_ENGINE_SUBSTITUTIONnằm trong tất cả các cột SELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;nhưng tôi vẫn gặp lỗi cho datetime không hợp lệ 0000-00-00 00:00:00cho đến khi tôi thực hiện lại truy vấn đầu tiên set global sql_mode="NO_ENGINE_SUBSTITUTION";Có ý tưởng nào không?
Smamatti

Giải pháp trong trường hợp của tôi là loại bỏ NO_ZERO_IN_DATE,NO_ZERO_DATEtrong phiên bản dòng my.ini của bạn xác định sql_mode.
Smamatti

1

Điều này là vô cùng xấu xí, nhưng nó cũng khắc phục vấn đề nhanh chóng cho tôi. Bảng của bạn cần một khóa duy nhất mà bạn sẽ sử dụng để sửa các cột bị nhiễm độc. Trong ví dụ này, khóa chính được gọi là 'id' và cột dấu thời gian bị hỏng được gọi là 'BadColumn'.

  1. Chọn ID của các cột bị nhiễm độc.

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

  2. Thu thập ID thành một chuỗi được phân cách bằng dấu phẩy. Ví dụ : 1, 22, 33. Tôi đã sử dụng một trình bao bọc bên ngoài cho điều này (một tập lệnh Perl) để nhanh chóng nhổ tất cả chúng ra.

  3. Sử dụng danh sách ID của bạn để cập nhật các cột cũ có ngày hợp lệ (1971 đến 2038).

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


1

Giải pháp của tôi

SET sql_mode='';
UPDATE tnx_k2_items
SET created_by = 790
, modified = '0000-00-00 00:00:00'
, modified_by = 0

1

Thay vì

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

Sử dụng

UPDATE your_table SET your_column = new_valid_value where your_column = 0;

0

Nếu bạn đang nhập dữ liệu theo cách thủ công, bạn có thể xem xét xóa các giá trị và số không trên TIMESTAMP (6) .000000 để nó trở thành TIMESTAMP. Điều đó làm việc tốt với tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.