2016-07-24 1 views
1

Für meinen Tisch admin_tool_functionalityDatetime-Feld Überlauf, wenn das Datum> '9999-12-31 23: 59: 59.4'

CREATE TABLE admin_tool_functionality (

    id BIGINT NOT NULL AUTO_INCREMENT, 

    admin_tool_functionality_type_id BIGINT NOT NULL, 

    CONSTRAINT fk__admin_tool_functionality__admin_tool_functionality_type 
     FOREIGN KEY (admin_tool_functionality_type_id) 
     REFERENCES admin_tool_functionality_type(id), 

    PRIMARY KEY (id, admin_tool_functionality_type_id), 

    price FLOAT NOT NULL, 

    valid_from_day DATETIME NOT NULL, 

    valid_until_day DATETIME NOT NULL, 

    CHECK(valid_from_day < valid_until_day) 

); 

Diese Insertion funktioniert:

INSERT INTO admin_tool_functionality 
    (admin_tool_functionality_type_id, price, valid_from_day, valid_until_day) 
VALUES 
    (1, 13.37, '2016-01-01', '9999-12-31 23:59:59.4'); 

Aber jeder Wert lager als '9999-12-31 23:59:59.4'

INSERT INTO admin_tool_functionality 
    (admin_tool_functionality_type_id, price, valid_from_day, valid_until_day) 
VALUES 
    (1, 13.37, '2016-01-01', '9999-12-31 23:59:59.5'); 

Geben Sie mir:

012.351 versagt
Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Datetime function: datetime field overflow 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3964) 
    at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3902) 
    at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2526) 
    at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2673) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2545) 
    at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2503) 
    at com.mysql.jdbc.StatementImpl.executeInternal(StatementImpl.java:839) 
    at com.mysql.jdbc.StatementImpl.execute(StatementImpl.java:739) 

trotz der documentation sagen

der Bereich für DATETIME Werte ist '1000-01-01 00:00:00.000000' zu '9999-12-31 23:59:59.999999'

Warum bin ich diesen Fehler?

+0

Zeitzonen, vielleicht? Das scheint ein seltsamer Randfall zu sein ... – ceejayoz

Antwort

2

Siehe Dokumentation fractional seconds für MySQL und beachten Sie die @Pieter-Kommentare zur MySQL-Version.

Vor MySQL die Mikrosekunden 5.6.4 verworfen und nicht gespeichert, sondern können in den folgenden Situationen gemäß der Dokumentation verwendet werden:

Ein Hinterbruchteil in Kontexten zulässig ist, wie Literalwerte, und in die Argumente zu oder geben Werte von einigen temporalen Funktionen zurück.

An oder nach MySQL 5.6.4 wurde die Unterstützung von Sekundenbruchteilen erweitert.

Sofern Sie Sekundenbruchteile (fsp) für Ihre DATETIME Spalte definieren, wird es auf 0 das heißt ohne Mikrosekunden Standard.

Basierend auf diesem Kommentar in der Dokumentation:

einen TIME, DATE oder TIMESTAMP-Wert mit einem Sekundenbruchteil in eine Spalte des gleichen Typs einsetzen, aber in Runden

weniger Nachkommastellen Ergebnisse mit

Eine Annahme und Theorie auf dem obigen Kommentar basiert und Ihre INSERT Fehler ist, dass 0,4 oder sogar 0,499999 (bis zu 6 Nachkommastellen, die MySQL 5.6.4 oder höher unterstützt) nach unten, während 0,5 abrunden wird oder größer wird Runde bis.

Da Mikrosekunden berücksichtigt werden fraktionierte, dass die Sekunden des integer oder ganzen Teil der Nummer machen würde. Wenn 59.5 aufrunden würde, würde dies dazu führen, dass sich Ihr Datumsteil ändern müsste (1 Tag vorrücken), da der Zeitteilbereich 00:00:00 bis 23:59:59 ist. Dieses Verhalten kann außerhalb einer Funktion, die Datum und Uhrzeit anpasst, als unerwartet angesehen werden.

+0

Okay, das macht jetzt Sinn. Ich benutze gerade 5.6.24! Danke für die Erklärung! – displayname

2

Fractional Sekunden wurde die Unterstützung für TIME, DATETIME und TIMESTAMP seit MySQL 5.6.4 hinzugefügt. Vor dieser Version dürfen Sie keine Sekunden zu Zeitstempeln hinzufügen (siehe documentation).

Haben Sie zufällig eine MySQL-Version vor 5.6.4?