Daugiau
MySQL Neteisingas datos laikas: '0000-00-00 00:00:00'
Neseniai perėmiau seną projektą, kuris buvo sukurtas prieš 10 metų. Jame naudojama MySQL 5.1.
Be kitų dalykų, man reikia pakeisti numatytąjį simbolių rinkinį iš latin1 į utf8.
Pavyzdžiui, turiu tokias lenteles:
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
Aš sukūriau savo "Mac" kompiuterį, kad galėčiau su tuo dirbti. Per daug negalvodamas paleidau "brew install mysql", kuris įdiegė MySQL 5.7. Taigi turiu tam tikrų versijų konfliktų.
Atsisiunčiau šios duomenų bazės kopiją ir ją importavau.
Jei bandau paleisti tokią užklausą:
ALTER TABLE users MODIFY first_name varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL
gaunu šią klaidą:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'created' at row 1
Maniau, kad galiu tai ištaisyti:
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
bet aš gaunu:
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
Ar turiu atnaujinti kiekvieną reikšmę?
124
3
Man nepavyko to padaryti:
(MySQL 5.7.13).
Aš vis gaudavau
Neteisingos datos reikšmės: '0000-00-00 00:00:00:00'
klaidą.Keista, bet tai veikė:
SELECT * FROM users WHERE created = '0000-00-00 00:00:00:00'
. Neįsivaizduoju, kodėl pirmasis variantas nepavyksta, o antrasis veikia... gal tai MySQL klaida?Bet kuriuo atveju ši UPDATE užklausa suveikė:
Stulpelio numatytoji reikšmė keičiama naudojant
ALTER TABLE
teiginį, pvz.... nekeičia jokių jau išsaugotų reikšmių. Numatytoji reikšmė taikoma įterptoms eilutėms, kurių stulpelio reikšmė nepateikta.
Klaida, su kuria susiduriate, gali būti, kad jūsų sesijos
sql_mode
nustatyme yraNO_ZERO_DATE
.Nuoroda: http://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sqlmode_no_zero_date
Kai atlikote "importą", SQL užklausos, kurios atliko INSERT į šią lentelę, buvo vykdomos sesijoje, kurioje leidžiama naudoti nulines datas.
Norėdami peržiūrėti sql_mode nustatymą:
-arba-
Kaip ištaisyti dabartinę problemą, kad paleidus
ALTER TABLE
komandą klaida nebūtų išmetama.Yra kelios galimybės:
sql_mode
, kad būtų leidžiama naudoti nulines datas, pašalindamiNO_ZERO_DATE
irNO_ZERO_IN_DATE
. Pakeitimą galima taikyti my.cnf faile, todėl iš naujo paleidus "MySQL" serverį kintamasissql_mode
bus inicializuotas pagal my.cnf nustatymą.Norėdami laikinai pakeisti nustatymą, jį galime pakeisti per vieną seansą, nereikalaudami visuotinio pakeitimo.
pakeiskite stulpelį
created
, kad jame būtų leidžiamos NULL reikšmės, ir atnaujinkite esamas eilutes, kad nulinės datos būtų pakeistos į nulines reikšmesatnaujinkite esamas eilutes, kad nulinės datos būtų pakeistos galiojančiomis datomis
Kiekvienai eilutei atnaujinti nereikia paleisti atskirų teiginių. Galime atnaujinti visas eilutes vienu šūviu (jei tai yra pakankamo dydžio lentelė. Didesnių lentelių atveju, kad būtų išvengta didžiulio grįžimo atgal ir (arba) pakartotinių operacijų generavimo, operaciją galime atlikti pakankamai didelėmis dalimis).
Klausime nurodyta lentelės apibrėžties
AUTO_INCREMENT
reikšmė užtikrina, kad eilučių skaičius nėra per didelis.Jei jau pakeitėme stulpelį
created
, kad jame būtų galima įrašytiNULL
reikšmes, galime daryti maždaug taip:Arba galime nustatyti galiojančią datą, pvz., 1970 m. sausio 2 d.
(Atkreipkite dėmesį, kad 1970 m. sausio 1 d. vidurnakčio datos reikšmė (
'1970-01-01 00:00:00:00'
) *yra "nulinė data". Ji bus įvertinta kaip'0000-00-00 00:00:00'
Mano pasiūlymas, jei lentelė yra tuščia arba nėra labai didelė, yra eksportuoti "create" teiginius kaip .sql failą ir perrašyti juos kaip norite. Tą patį padarykite ir tuo atveju, jei turite kokių nors esamų duomenų, t. y. eksportuokite įterpimo teiginius (rekomenduoju tai daryti atskirame faile kaip ir kūrimo teiginius). Galiausiai išmeskite lentelę ir vykdykite pirmiausia create, o paskui insert komandas.
Tam galite naudoti
mysqldump
komandą, įtrauktą į MySQL diegimo programą, arba galite įdiegti MySQL Workbench - nemokamą grafinę priemonę, kurioje taip pat yra tokia galimybė, kurią galima labai lengvai pritaikyti, neieškant konkrečių komandų parinkčių.