Saya baru-baru ini mengambil alih proyek lama yang dibuat 10 tahun lalu. Ini menggunakan MySQL 5.1.
Antara lain, saya perlu mengubah set karakter default dari latin1 ke utf8.
Sebagai contoh, saya punya tabel seperti ini:
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
Saya mengatur Mac saya sendiri untuk mengerjakan ini. Tanpa berpikir terlalu banyak tentang hal itu, saya menjalankan "brew install mysql" yang menginstal MySQL 5.7. Jadi saya punya beberapa konflik versi.
Saya mengunduh salinan database ini dan mengimpornya.
Jika saya mencoba menjalankan kueri seperti ini:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
Saya mendapatkan kesalahan ini:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Saya pikir saya bisa memperbaikinya dengan:
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
tapi saya mendapatkan:
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
Apakah saya harus memperbarui setiap nilai?
Saya tidak dapat melakukan ini:
(pada MySQL 5.7.13).
Saya terus mendapatkan
Incorrect datetime value: '0000-00-00 00:00:00'
kesalahan.Anehnya, ini bekerja:
SELECT * FROM users WHERE created = '0000-00-00 00:00:00'
. Saya tidak tahu mengapa yang pertama gagal dan yang terakhir berfungsi ... mungkin bug MySQL?Bagaimanapun, permintaan UPDATE ini berfungsi:
sumber
UPDATE users SET created = NULL WHERE created = '0'
entity
WHERE CreatedAt = "0000-00-00 00:00:00" berfungsi dengan baik, tetapi dengan kegagalan yang diperbarui! Saya memiliki masalah yang sama. Perbaiki dengan solusi @obe CAST (dibuat AS CHAR (20)) ... Saya rasa ini adalah bug.UPDATE users SET created = NULL WHERE created=0
(tanpa 'sekitar nol)Mengubah nilai default untuk kolom dengan
ALTER TABLE
pernyataan, mis... tidak mengubah nilai apa pun yang sudah disimpan. Nilai "default" berlaku untuk baris yang dimasukkan, dan nilai tidak disediakan untuk kolom.
Mengenai mengapa Anda mengalami kesalahan, kemungkinan
sql_mode
pengaturan untuk sesi Anda termasukNO_ZERO_DATE
.Referensi: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
Ketika Anda melakukan "impor", pernyataan SQL yang melakukan INSERT ke dalam tabel itu dijalankan dalam sesi yang memungkinkan nol tanggal.
Untuk melihat pengaturan sql_mode:
-atau-
Sejauh cara "memperbaiki" masalah saat ini, sehingga kesalahan tidak akan dibuang ketika Anda menjalankan
ALTER TABLE
pernyataan.Beberapa pilihan:
1) ubah
sql_mode
untuk mengizinkan nol tanggal, dengan menghapusNO_ZERO_DATE
danNO_ZERO_IN_DATE
. Perubahan dapat diterapkan dalam file my.cnf, jadi setelah restart Server MySQL,sql_mode
variabel akan diinisialisasi ke pengaturan di my.cnf.Untuk perubahan sementara, kami dapat memodifikasi pengaturan dengan satu sesi, tanpa memerlukan perubahan global.
2) ubah
created
kolom untuk memungkinkan nilai NULL, dan perbarui baris yang ada untuk mengubah tanggal nol ke nilai nol3) perbarui baris yang ada untuk mengubah tanggal nol ke tanggal yang valid
Kami tidak perlu menjalankan pernyataan individual untuk memperbarui setiap baris. Kita dapat memperbarui semua baris dalam satu gerakan (dengan asumsi itu adalah tabel berukuran cukup. Untuk tabel yang lebih besar, untuk menghindari rollback / undo generasi yang luar biasa, kita dapat melakukan operasi dalam potongan berukuran cukup.)
Dalam pertanyaan,
AUTO_INCREMENT
nilai yang ditunjukkan untuk definisi tabel meyakinkan kita bahwa jumlah baris tidak berlebihan.Jika kami telah mengubah
created
kolom untuk memungkinkanNULL
nilai, kami dapat melakukan sesuatu seperti ini:Atau, kita dapat mengaturnya ke tanggal yang valid, misalnya 2 Januari 1970
(Perhatikan bahwa nilai waktu tengah malam 1 Januari 1970 (
'1970-01-01 00:00:00'
) adalah "tanggal nol". Itu akan dievaluasi menjadi'0000-00-00 00:00:00'
sumber
sql_mode
. Versi MySQL yang lebih baru memiliki pengaturan standarsql_mode
yang lebih ketat dari versi sebelumnya. Referensi untuk 8,0 sini: dev.mysql.com/doc/refman/8.0/en/sql-mode.html lihatNO_ZERO_DATE
,ALLOW_INVALID_DATE
, et al. perhatikan bahwa beberapa termasuk dalam mode STRICT misalnyaSTRICT_TRANS_TABLES
,STRICT_ALL_TABLES
dan mode kombo lainnya. Untuk mengatasinya, modifikasi sementara sql_mode untuk sesi ini,Saya memperbaikinya dengan melakukan ini sebelum permintaan
sumber
Menurut Manual Referensi MySQL 5.7 :
Karena
0000-00-00 00:00:00
bukanDATETIME
nilai yang valid , basis data Anda rusak. Itulah sebabnya MySQL 5.7 - yang dilengkapi denganNO_ZERO_DATE
mode yang diaktifkan secara default - menghasilkan kesalahan saat Anda mencoba melakukan operasi penulisan.Anda dapat memperbaiki tabel Anda dengan memperbarui semua nilai yang tidak valid ke nilai lain yang valid, seperti
NULL
:Juga, untuk menghindari masalah ini, saya sarankan Anda selalu mengatur waktu saat ini sebagai nilai default untuk
created
bidang -seperti Anda , sehingga mereka terisi secara otomatisINSERT
. Kerjakan saja:sumber
sumber
Inilah solusi saya PhpMyAdmin / Fedora 29 / MySQL 8.0 (misalnya):
set sql_mode='SOMETHING';
tidak berfungsi , perintah panggilan berhasil tetapi tidak ada yang berubah.set GLOBAL sql_mode='SOMETHING';
ubah konfigurasi global, perubahan permanen.set SESSION sql_mode='SOMETHING';
ubah konfigurasi sesi, variabel SESI hanya memengaruhi klien saat ini.https://dev.mysql.com/doc/refman/8.0/id/sql-mode.html
Jadi saya melakukan ini:
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'
Anda dapat menghapus atau menambahkan mode lain dengan cara yang sama.
Ini berguna untuk mengubah global untuk menggunakan dan menguji kerangka kerja atau sql_mode harus ditentukan dalam setiap file atau sekelompok pertanyaan.
Diadaptasi dari pertanyaan yang diajukan di sini: bagaimana-bisa-saya-menonaktifkan-mode -sql-ketat
Contoh: instal konten Joomla 4.0-alpha terbaru.
Sunting: Di PhpMyadmin, jika Anda memiliki kontrol server, Anda dapat mengubah
sql_mode
(dan semua parameter lainnya) langsung diPlus > Variables > sql_mode
sumber
Anda dapat mengubah jenis diciptakan lapangan dari
datetime
kevarchar(255)
, maka Anda dapat mengatur (update) semua catatan yang memiliki nilai"0000-00-00 00:00:00"
untukNULL
.Sekarang, Anda dapat melakukan pertanyaan tanpa kesalahan. Setelah Anda selesai, Anda dapat mengubah jenis bidang diciptakan untuk
datetime
.sumber
Saya memiliki kesalahan ini juga setelah memutakhirkan MySQL dari 5.6 ke 5.7
Saya menemukan bahwa solusi terbaik bagi saya adalah menggabungkan beberapa solusi di sini dan membuat sesuatu yang bekerja dengan input minimum.
Saya menggunakan MyPHPAdmin untuk kesederhanaan mengirimkan pertanyaan melalui antarmuka karena dengan begitu saya dapat memeriksa struktur dan semua itu dengan mudah. Anda mungkin menggunakan ssh secara langsung atau antarmuka lain. Metode ini harus sama atau sama saja.
...
1.
Pertama-tama periksa kesalahan aktual saat mencoba memperbaiki db:
Ini memberitahu saya kolom checked_out_time dalam tabel jos_menu perlu memiliki semua tanggal buruk diperbaiki serta "default" berubah.
...
2.
Saya menjalankan query SQL berdasarkan info dalam pesan kesalahan:
Jika Anda mendapatkan kesalahan, Anda dapat menggunakan kueri di bawah ini yang sepertinya selalu berfungsi:
...
3.
Kemudian setelah selesai saya menjalankan query SQL kedua:
Atau dalam kasus ini adalah tanggal yang harus NULL
...
Jika saya menjalankan database perbaikan sekarang saya mendapatkan:
joomla.jos_menu OK
...
Bekerja dengan baik :)
sumber
Memeriksa
jika Anda melihat hal-hal 'ZERO_DATE' di sana, coba
Logout dan kembali lagi ke klien Anda (ini aneh) dan coba lagi
sumber
Jadikan mode sql tidak ketat
jika menggunakan laravel, pergi ke config-> database, pergi ke pengaturan mysql dan buat mode ketat salah
sumber
Saya memiliki masalah yang sama tetapi dalam kasus saya beberapa baris memiliki nilai NULL.
jadi pertama saya perbarui tabel:
masalah terpecahkan, setidaknya dalam kasus saya.
sumber
Saya juga punya
info kesalahan
Perbaiki ini dengan mengubah
0000-00-00 00:00:00
ke1970-01-01 08:00:00
1970-01-01 08:00:00
cap waktu unix adalah 0sumber
NO_ZERO_DATE
Saya menemukan solusinya di https://support.plesk.com/hc/en-us/articles/115000666509-How-to-change-the-SQL-mode-in-MySQL . Saya punya ini:
Perhatikan
NO_ZERO_IN_DATE,NO_ZERO_DATE
hasil di atas. Saya menghapusnya dengan melakukan ini:Lalu aku punya ini:
Setelah melakukan itu, saya bisa menggunakan dengan
ALTER TABLE
sukses dan mengubah tabel saya.sumber
Inilah yang saya lakukan untuk menyelesaikan masalah saya. Saya diuji di MySQL 5.7 ubuntu 18.04 lokal.
Sebelum menjalankan query ini secara global, saya menambahkan file cnf di direktori /etc/mysql/conf.d . Nama file cnf adalah mysql.cnf dan kode
Kemudian saya restart mysql
Semoga ini bisa membantu seseorang.
sumber
NO_ENGINE_SUBSTITUTION
di semua kolomSELECT @@global.sql_mode, @@session.sql_mode, @@sql_mode;
tapi saya masih mendapatkan kesalahan untuk datetime yang tidak valid0000-00-00 00:00:00
sampai saya menjalankan query pertama lagiset global sql_mode="NO_ENGINE_SUBSTITUTION";
Ada ide?NO_ZERO_IN_DATE,NO_ZERO_DATE
versi baris my.ini Anda yang mendefinisikansql_mode
.Ini sangat jelek, tetapi juga memperbaiki masalah dengan cepat untuk saya. Tabel Anda memerlukan kunci unik yang akan Anda gunakan untuk memperbaiki kolom yang tercemar. Dalam contoh ini, kunci utama disebut 'id' dan kolom cap waktu yang rusak disebut 'BadColumn'.
Pilih ID dari kolom yang ternoda.
select id from table where BadColumn='0000-00-00 00:00:00'
Kumpulkan ID menjadi string yang dibatasi koma. Contoh:
1, 22, 33
. Saya menggunakan pembungkus eksternal untuk ini (skrip Perl) dengan cepat memuntahkan semuanya.Gunakan daftar ID Anda untuk memperbarui kolom lama dengan tanggal yang valid (1971 hingga 2038).
update table set BadColumn='2000-01-01 00:00:00' where id in (1, 22, 33)
sumber
Solusi saya
sumber
Dari pada
Menggunakan
sumber
Jika Anda memasukkan data secara manual, Anda dapat mempertimbangkan untuk menghapus nilai dan nol pada TIMESTAMP (6) .000000 sehingga menjadi TIMESTAMP. Itu berhasil dengan saya.
sumber