'0000-00-00 00:00:00' java.sql olarak gösterilemez. Zaman damgası hatası


141

Tarihleri ​​içeren bir veritabanı tablo var

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

MySQL kullanıyorum. Programdan bazen veriler tarih olmadan veritabanına aktarılır. Bu nedenle, 0000-00-00 00:00:00 tablo verisi hata verdiği tarih sütunuyla çağrıldığında tarih değeri otomatik olarak atanır

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

Veri eklerken tarihe null değer iletmeye çalıştım, ancak geçerli saate atanıyor.

ResultSetTablo yapısını değiştirmeden alabilmemin bir yolu var mı ?

Yanıtlar:


302

Bu JDBC URL'sini doğrudan veri kaynağı yapılandırmanızda kullanabilirsiniz:

jdbc: mysql: // sunucunuz: 3306 / yourdatabase zeroDateTimeBehavior = convertToNull


2
Meraklı. Diğer cevapları okumak, ah, sıfır ay yok. Bu gerçekten ne anlama geliyor?
Thufir

2
Jdbc URL'ime eklenecek bir MariaDB eşdeğeri olup olmadığını biliyor musunuz? jdbc: mariadb: // localhost: 3306 / dev? zeroDateTimeBehavior = convertToNull benim için çalışmıyor gibi görünüyor.
jeffkempf

Benim için CONVERT_TO_NULL
olmalıydı

16

"Tarih" "0000-00-00" 'un geçerli bir "tarih" olup olmadığı sorusu ile ilgisizdir. "Sadece veritabanını değiştirmek" nadiren uygulanabilir bir çözümdür.

Gerçekler:

  • MySQL, sıfır değerine sahip bir tarihe izin verir.
  • Bu "özellik" diğer dillerde yaygın olarak kullanılmaktadır.

Yani, "sadece veritabanını değiştirmek", binlerce satır PHP kodu kırılacak.

Java programcılarının MySQL sıfır tarihini ve diğer diller bu "özelliği" güvenmek ne zaman veritabanı, içine bir sıfır tarih geri koymak gerekir.

MySQL'e bağlanan bir programcının boş tarihleri ​​ve 0000-00-00'ü geçerli tarihlerle işlemesi gerekir. 0000-00-00 değerini null olarak değiştirmek uygun bir seçenek değildir, çünkü o zaman artık veritabanına geri yazmak için tarihin 0000-00-00 olup olmayacağını belirleyemezsiniz.

0000-00-00 için, tarih değerini bir dize olarak kontrol etmenizi ve ardından ("y", 1) veya ("yyyy-AA-dd", 0001-01-01) olarak veya herhangi bir geçersiz olarak değiştirmenizi öneririm MySQL tarihi (1000 yıldan az, iirc). MySQL'in başka bir özelliği daha vardır: düşük tarihler otomatik olarak 0000-00-00 biçimine dönüştürülür.

Önerimin bir çamur olduğunu anlıyorum. Ancak MySQL'in tarih işlemesi de öyle. Ve iki kludge bunu düzeltmiyor. Mesele şu ki, birçok programcı MySQL sıfır tarihlerini sonsuza kadar işlemek zorunda kalacak .


9

JDBC-mysql protokolüne aşağıdaki ifadeyi ekleyin:

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

Örneğin:

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

5
Bu yaklaşıma dikkat edin. Bir cazibe gibi çalışır ama bize bir üretim sunucusu aşağı aldı (mükemmel olsa dev çalıştı ...). Öğrendiğimiz şey, dizeyi &
nbsp

6

0000-00-00 00:00:00Veya gibi sahte tarihler kullanmak yerine 0001-01-01 00:00:00(ikincisi geçerli bir tarih olarak kabul edilmelidir), NULLdeğerlere izin vermek için veritabanı şemanızı değiştirin .

ALTER TABLE table_name MODIFY COLUMN date TIMESTAMP NULL

3

Eklenti dönüşü olarak, tarih sütununuzda değişiklik yapamadığınız veya değerleri güncelleyemediğinizde veya bu değişiklikler yapılırken, büyük / küçük harf kullanarak bir seçim yapabilirsiniz.

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

Bu sorunla boğuştum ve yukarıdaki kabul edilen cevapta @Kushan'ın katkıda bulunduğu URL birleştirme çözümünü uyguladım. Yerel MySql örneğimde çalıştı. Ancak Play / Scala uygulamamı Heroku'ya yerleştirdiğimde artık çalışmaz. Heroku ayrıca, kullanıcılarına sağladıkları DB URL'sine ve bu çözümü, Heroku'nun "?" kendi argüman kümesinden önce, çalışmaz. Ancak, eşit derecede iyi işleyen farklı bir çözüm buldum.

SET sql_mode = 'NO_ZERO_DATE';

Bunu tablo açıklamalarıma koydum ve '0000-00-00 00:00:00' probleminin java.sql.timestamp olarak temsil edilememesi sorununu çözdüm


1

böyle deneyebilirsiniz

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

0000 yılı yoktu ve 00 ayı ya da 00 günü yok. Denemenizi öneririm

0001-01-01 00:00:00

Bazı standartlarda 0 yılı tanımlanmış olsa da, yararlı IMHO'dan daha kafa karıştırıcı olması daha olasıdır.


2
Evet, 0000 yılı var. 0 yılını etkiledi ve -1 yılımız ve -1000 yılı var. Bu Gregoryen takvimi veya bu Anno Domini'yi ve daha özel olarak Gregoryen takviminin sıfır yılı yok, ancak iso var ve iso kullanılıyor bij bilgisayarlar 0 yıl
botenvouwer

@sirwilliam İlginç nitelikler için teşekkür ederim. OP'nin 0 yılının NULL veya var olmayan bir şey olarak ele alınmasını istediği anlaşılıyor.
Peter Lawrey

1
MySQL'de 0000-00-00 00:00:00 0'a eşittir. Eski kodda buna dayanan bazı sorgular olabilir.
Juha Palomäki


0

Bunun geç bir cevap olacağını biliyorum, ama işte en doğru cevap bu.

MySQL veritabanında timestampvarsayılan değerinizi olarak değiştirin CURRENT_TIMESTAMP. Sahte değere sahip eski kayıtlarınız varsa, bunları manuel olarak düzeltmeniz gerekir.


bu da yardımcı olmaz.
Sunil Sharma

0

Gerekmiyorsa, mysql tablosundaki sütundan "null değil" özelliğini kaldırabilirsiniz. "null değil" özelliğini kaldırdığınızda "0000-00-00 00:00:00" dönüşümü gerekmez ve sorun ortadan kalkar.

En azından benim için çalıştı.


-2

Bu logstash aracılığıyla veri pompalama istisnası aşağıda kim almak için tam yardım olduğuna inanıyorum Hata: logstash.inputs.jdbc - JDBC sorgusu yürütülürken istisna {: exception => #}

Cevap: jdbc: mysql: // localhost:? 3306 / database_name zeroDateTimeBehavior = convertToNull"

veya mysql ile çalışıyorsanız

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.