„0000-00-00 00:00:00” nie może być reprezentowane jako błąd java.sql.Timestamp


141

Mam tabelę bazy danych zawierającą daty

 (`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'). 

Używam MySQL. Z programu czasami dane są przekazywane do bazy danych bez daty. Tak więc wartość daty jest automatycznie przypisywana, 0000-00-00 00:00:00 gdy wywoływana jest tabela danych z kolumną daty, w której występuje błąd

...'0000-00-00 00:00:00' can not be represented as java.sql.Timestamp.......

Próbowałem przekazać wartość null do daty podczas wstawiania danych, ale zostaje ona przypisana do aktualnego czasu.

Czy jest jakiś sposób, aby uzyskać to ResultSetbez zmiany struktury tabeli?

Odpowiedzi:


302

Możesz użyć tego adresu URL JDBC bezpośrednio w konfiguracji źródła danych:

jdbc: mysql: // yourserver: 3306 / yourdatabase? zeroDateTimeBehavior = convertToNull


2
ciekawy. Czytając inne odpowiedzi, duh, nie ma miesiąca zerowego. Co to naprawdę oznacza?
Thufir,

2
Czy wiesz, czy istnieje odpowiednik MariaDB, który można dołączyć do mojego adresu URL jdbc? jdbc: mariadb: // localhost: 3306 / dev? zeroDateTimeBehavior = convertToNull nie działa dla mnie.
jeffkempf

Musiał być dla mnie CONVERT_TO_NULL
routeburn

16

To, czy „data” „0000-00-00” jest prawidłową „datą”, nie ma znaczenia dla pytania. „Po prostu zmień bazę danych” rzadko jest dobrym rozwiązaniem.

Fakty:

  • MySQL dopuszcza datę o wartości zerowej.
  • Ta „funkcja” jest szeroko stosowana w innych językach.

Tak więc, jeśli „po prostu zmienię bazę danych”, tysiące linii kodu PHP zostanie przerwanych.

Programiści Java muszą zaakceptować datę zerową MySQL i muszą umieścić datę zerową z powrotem w bazie danych, gdy inne języki polegają na tej „funkcji”.

Programista łączący się z MySQL musi obsługiwać wartości null i 0000-00-00 oraz prawidłowe daty. Zmiana 0000-00-00 na null nie jest realną opcją, ponieważ wtedy nie można już określić, czy oczekiwana data to 0000-00-00 do zapisu z powrotem do bazy danych.

W przypadku 0000-00-00 proponuję sprawdzić wartość daty jako ciąg znaków, a następnie zmienić ją na („y”, 1) lub („yyyy-MM-dd”, 0001-01-01) lub na dowolny nieprawidłowy Data MySQL (mniej niż rok 1000, iirc). MySQL ma jeszcze jedną „funkcję”: niskie daty są automatycznie konwertowane na 0000-00-00.

Zdaję sobie sprawę, że moja sugestia jest niezdarna. Ale tak samo jest z obsługą dat w MySQL. A dwa bzdury nie pomagają. Faktem jest, że wielu programistów będzie musiało wiecznie obsługiwać daty zerowe MySQL .


9

Dołącz następującą instrukcję do protokołu JDBC-mysql:

?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

na przykład:

jdbc:mysql://localhost/infra?zeroDateTimeBehavior=convertToNull&autoReconnect=true&characterEncoding=UTF-8&characterSetResults=UTF-8

5
Uważaj przy takim podejściu. Działa jak urok, ale zepsuło nam serwer produkcyjny (chociaż działało doskonale w programistach ...). Dowiedzieliśmy się, że musisz zacytować ciąg, ponieważ & jest interpretowane jako znak specjalny w niektórych kontekstach, nadając linii zupełnie inne znaczenie ...
Techmag

6

Zamiast używać fałszywych dat, takich jak 0000-00-00 00:00:00lub0001-01-01 00:00:00 (ta ostatnia powinna zostać zaakceptowana, ponieważ jest prawidłowa), zmień schemat bazy danych, aby zezwolić na NULLwartości.

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL

3

W ostatecznym rozrachunku, kiedy nie możesz zmienić kolumny z datą lub zaktualizować wartości, lub gdy mają miejsce te modyfikacje, możesz dokonać wyboru przy użyciu przypadku / kiedy.

SELECT CASE ModificationDate WHEN '0000-00-00 00:00:00' THEN '1970-01-01 01:00:00' ELSE ModificationDate END AS ModificationDate FROM Project WHERE projectId=1;

1

Zmagałem się z tym problemem i wdrożyłem rozwiązanie do konkatenacji adresów URL dostarczone przez @Kushan w zaakceptowanej odpowiedzi powyżej. Zadziałało w mojej lokalnej instancji MySql. Ale kiedy wdrożyłem aplikację Play / Scala na Heroku, przestała ona działać. Heroku łączy również kilka argumentów z adresem URL bazy danych, które dostarczają użytkownikom, oraz to rozwiązanie, ponieważ Heroku używa konkatenacji „?” przed ich własnym zestawem argumentów, nie zadziała. Jednak znalazłem inne rozwiązanie, które wydaje się działać równie dobrze.

SET sql_mode = 'NO_ZERO_DATE';

Umieściłem to w moich opisach tabel i rozwiązałem problem „0000-00-00 00:00:00”, którego nie można przedstawić jako java.sql.


1

możesz spróbować w ten sposób

ArrayList<String> dtlst = new ArrayList<String>();
String qry1 = "select dt_tracker from gs";

Statement prepst = conn.createStatement();
ResultSet rst = prepst.executeQuery(qry1);
while(rst.next())
{
    String dt = "";
    try
    {
        dt = rst.getDate("dt_tracker")+" "+rst.getTime("dt_tracker");
    }
    catch(Exception e)
    {
        dt = "0000-00-00 00:00:00";
    }

    dtlst.add(dt);
}

0

Nie było roku 0000 i nie ma miesiąca 00 ani dnia 00. Proponuję spróbować

0001-01-01 00:00:00

Chociaż w niektórych standardach zdefiniowano rok 0, jest bardziej prawdopodobne, że będzie on zagmatwany niż przydatna IMHO.


2
Tak, istnieje rok 0000. w rzeczywistości jego rok 0 i mamy rok -1 i rok -1000. Nigdy nie widziałem tego kalendarza gregoriańskiego ani tego Anno Domini, a zwłaszcza kalendarz gregoriański nie ma roku zerowego, ale iso ma, a iso jest używane komputery bij patrz 0 rok
botenvouwer

@sirwilliam Dziękuję za interesujące kwalifikacje. Wygląda na to, że OP chciał, aby rok 0 był traktowany jako NULL lub coś, co nie istnieje.
Peter Lawrey,

1
W MySQL 0000-00-00 00:00:00 jest równe 0. W starszym kodzie mogą istnieć zapytania, które na tym polegają.
Juha Palomäki


0

Wiem, że to będzie późna odpowiedź, ale tutaj jest najbardziej poprawna odpowiedź.

W bazie danych MySQL zmień timestampdomyślną wartość na CURRENT_TIMESTAMP. Jeśli masz stare rekordy z fałszywą wartością, będziesz musiał ręcznie je naprawić.


to też nie pomoże.
Sunil Sharma

0

Jeśli nie jest to konieczne, możesz usunąć właściwość „not null” z kolumny w tabeli mysql. po usunięciu właściwości „not null” nie ma potrzeby konwersji „0000-00-00 00:00:00” i problem zniknie.

Przynajmniej pracował dla mnie.


-2

Uważam, że jest to pełna pomoc dla tych, którzy otrzymują to poniżej Wyjątek dotyczący pompowania danych przez logstash Błąd: logstash.inputs.jdbc - wyjątek podczas wykonywania zapytania JDBC {: wyjątek => #}

Odpowiedź: jdbc: mysql: // localhost: 3306 / database_name? ZeroDateTimeBehavior = convertToNull "

lub jeśli pracujesz z mysql

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.