sql >> Databasteknik >  >> RDS >> Mysql

MySQL infoga till DATETIME:är det säkert att använda formatet ISO::8601?

Det ser ut som att det korta svaret på denna fråga är "Nej, det är inte säkert" - denna slutsats följer en serie experiment med MySQL-skal. Skulle ändå uppskatta ett mer "teoretiskt" svar...

Tydligen är MySQL-motorn (som standard) ganska liberal i vad den accepterar som en Datetime-literal även med sql_mode inställd på STRICT_ALL_TABLES :inte bara olika separatorer accepteras, de kan också skilja sig åt:

INSERT INTO t(dt) VALUES('2012-01,03.04:[email protected]'); -- Query OK, 1 row affected

Dessutom, om strängen är för kort kommer den att fyllas med nollor... men det kan finnas överraskningar:

INSERT INTO t(dt) VALUES('2012011'); -- 2020-12-01 01:00:00 is what's inserted

Det tråkiga är att strängen för lång (när den sista parserbara siffran följs av något annat än blanksteg) kommer att betraktas som ett ogiltigt värde i strikt läge:

mysql> INSERT INTO t(dt) VALUES('2012-06-27T05:25Z');
ERROR 1292 (22007): Incorrect datetime value: '2012-06-27T05:25Z' for column 'dt' at row 1
mysql> INSERT INTO t(dt) VALUES('2012-06-27T05:25');
Query OK, 1 row affected (0.10 sec)

I det traditionella läget är analysen ännu mer avslappnad - men inte mer exakt; dessutom kommer strängarna som anses felaktiga i det strikta läget att ge en sorts "tysta varningar", även om operationerna kommer att lyckas:

mysql> INSERT INTO t(dt) VALUES('2012-06-27T05:25Z');
Query OK, 1 row affected, 1 warning (0.10 sec)

mysql> SHOW WARNINGS;
+---------+------+---------------------------------------------+
| Warning | 1264 | Out of range value for column 'dt' at row 1 |
+---------+------+---------------------------------------------+

mysql> SELECT dt FROM t;
+---------------------+
| dt                  |
+---------------------+
| 2012-06-27 05:25:00 |
+---------------------+

Summan av kardemumman är att vi var tvungna att skriva om någon DAL-relaterad kod så att datum (och datumtider) alltid skickas till DB i "normaliserad" form. Jag undrar varför det är vi som måste göra det, och inte Zend_Db-utvecklare. Men det är en annan historia, antar jag. )



  1. Dynamisk markör i lagrad procedur

  2. kodning UTF8 matchar inte locale en_US; den valda LC_CTYPE-inställningen kräver kodning av LATIN1

  3. Fel:kunde inte initiera huvudinformationsstrukturen när man utförde masterslavreplikering i MySQL

  4. Skript för att döda alla anslutningar till en databas (mer än RESTRICTED_USER ROLLBACK)