PDA

View Full Version : Datum '01.01.0001' per JDBC in Datenbank schreiben



mwithake
19-04-07, 15:25
Hallo,

wir arbeiten mit Datumsfelder ohne null-Behandlung (date not null). Nicht gefüllte Datumsfelder werden mit '01.01.0001' vorbelegt.

Hat jemand eine Idee, wie ich es hinbekomme unter Java mit JDBC Datumsfelder mit Wert '01.01.0001' zu füllen?

Gruß
M. Withake

BenderD
19-04-07, 19:28
Ja, aber wo ist das Problem?


Hallo,

wir arbeiten mit Datumsfelder ohne null-Behandlung (date not null). Nicht gefüllte Datumsfelder werden mit '01.01.0001' vorbelegt.

Hat jemand eine Idee, wie ich es hinbekomme unter Java mit JDBC Datumsfelder mit Wert '01.01.0001' zu füllen?

Gruß
M. Withake

Fuerchau
19-04-07, 19:30
Das wird so wohl nicht gehen, da die meisten Date-Formate nur ab dem 1.1.0100 funktionieren.
Dies liegt wohl daran, dass ein Datum intern als Double-Wert in Anzahl Tage seit dem 31.12.1899 gespeichert werden.

2 = 1.1.1900

Werte < 0 liegen eben davor.

Hier kannst du nur mit Direkt-Sql was erreichen, in dem du das Datum im ISO-Format angibst:

insert into myfile (MyDate) values('0001-01-01')

Die weitere Alternative ist, du bestimmst für die Tabelle den Defaultwert '0001-01-01' und läßt beim Insert das Feld einfach aus:

create mytable (mydate as date not null default '0001-01-01')

Fuerchau
19-04-07, 19:34
@Dieter

Irgendwo liegt es an der Interpretation eines Datums.

Ist die Jahreszahl 2-Stellig wird eben selbständig 1900 oder 2000 addiert.
Erst wenn die Jahreszahl mindestens 3-stellig ist (also 100), bleibt sie wie sie ist.

BenderD
20-04-07, 06:43
@Baldur: zweistellig gibt es in Java nicht für Jahreszahlen, da gibt es nur int und da wo das bei 1900 aufsetzt, sagt man halt -1899, wenn man das Jahr 1 haben will.
Auch mit dem Monaten hat das Tücken, die gehen hie und da von 0 bis 11, da muss man 0 nehmen, wenn man 1 drinstehen haben will.
Aber all dies ist mit good old RTFM lösbar und Herr Google liefert sogar Beispiele.
Da gibt es noch weitere Möglichkeiten, was man mit Datümern an Irrtümern produzieren kann, von der Dateierstellung, über Systemwerte der AS/400, den Treiber und Treibereinstellungen bis hin zum Java Programm.

Summa Summarum: wer sich ein wenig mehr Mühe beim Fragen gibt, bekommt auch schnell und präzise Antworten.

mfg

Dieter Bender


@Dieter

Irgendwo liegt es an der Interpretation eines Datums.

Ist die Jahreszahl 2-Stellig wird eben selbständig 1900 oder 2000 addiert.
Erst wenn die Jahreszahl mindestens 3-stellig ist (also 100), bleibt sie wie sie ist.

mwithake
20-04-07, 08:17
@Dieter Es ging darum den Wert mit der Methode setDate() der Klasse PreparedStatement zu schreiben und ich keine java.sql.Date-Objekt mit dem entsprechende Wert für '01.01.0001' hinbekam.

Habe inzwischen aber eine Lösung gefunden:


GregorianCalendar cal = (GregorianCalendar)GregorianCalendar.getInstance() ;
cal.set(1, 0, 1, 0, 0, 0);
Date emptyDate = new Date(cal.getTimeInMillis());


oder kurz


Date emptyDate = new Date(-62135773199359l)

Wir nutzten den Wert '01.01.0001' als "Leerwert" weil ein RPG-CLEAR auf ein Datumsfeld genau diesen Wert ergibt und wir auf das umständlichen Handling von NULL-Werten in der Datenbank ansonsten gut verzichten können.

Gruß
M. Withake

Fuerchau
20-04-07, 08:39
Die AS/400 akzeptiert ein Datum auch als String im ISO-Format.

BenderD
20-04-07, 17:10
Hallo,

das habe ich mir schon gedacht, dass da prepared Statement und Date im Spiel ist; dabei ist halt die Tücke, dass da auf das Jahr 1900 draufgezählt werden - nimmt man da -1899, dann passt es.
Wenn der Treiber das alles richtig macht, und die Datenbank mit not null und default 1.1.0001 definiert ist, dann müsste man eigentlich auch mit prepStm.setDate(n, null) den gewünschten Effekt erreichen.
Ansonste müsste eigentlich auch DateFormat.parse("01.01.0001") zum gewünschten Ziel führen.

mfg

Dieter Bender


@Dieter Es ging darum den Wert mit der Methode setDate() der Klasse PreparedStatement zu schreiben und ich keine java.sql.Date-Objekt mit dem entsprechende Wert für '01.01.0001' hinbekam.

Habe inzwischen aber eine Lösung gefunden:


GregorianCalendar cal = (GregorianCalendar)GregorianCalendar.getInstance() ;
cal.set(1, 0, 1, 0, 0, 0);
Date emptyDate = new Date(cal.getTimeInMillis());


oder kurz


Date emptyDate = new Date(-62135773199359l)

Wir nutzten den Wert '01.01.0001' als "Leerwert" weil ein RPG-CLEAR auf ein Datumsfeld genau diesen Wert ergibt und wir auf das umständlichen Handling von NULL-Werten in der Datenbank ansonsten gut verzichten können.

Gruß
M. Withake

Fuerchau
21-04-07, 09:18
Der Nachteil, wenn man ein Feld für den Insert benennt, zieht der Default der DB nicht !
Nur wenn beim Insert ein Feld nicht benannt wird, wird der Default genommen.
Setzt du das Feld auf NULL, gibts einen Fehler, wenn NULL nicht erlaubt ist.

Wie gesagt, die AS/400 und manche andere DB's erlauben auch Strings als Parameter, wenn das Datum eindeutig erkannt werden kann.
Dies ist bei der AS/400 eben das ISO-Format.

In VB löse ich das eben so:
if ... then
.Parameter(MyDate)="0001-01-01"
else
.Parameter(MyDate)=format(MyDate, "jjjj-mm-dd")
end if

Ich denke, für Java gibts ähnliches.

BenderD
21-04-07, 09:55
das mit dem Null war nicht einmal die zweitbeste Idee, das war mir um diese Zeit gerade nicht präsent. Aber Workarounds brauchts da in Java nicht, das Date Objekt kann auch den 1.1.0001 aufnehmen, ist allerdings nicht gerade das Highlight von Java und ein wenig hakelig - wens stört, der kann sich da auch einen kleinen Wrapper für schreiben.

mfg

Dieter Bender


Der Nachteil, wenn man ein Feld für den Insert benennt, zieht der Default der DB nicht !
Nur wenn beim Insert ein Feld nicht benannt wird, wird der Default genommen.
Setzt du das Feld auf NULL, gibts einen Fehler, wenn NULL nicht erlaubt ist.

Wie gesagt, die AS/400 und manche andere DB's erlauben auch Strings als Parameter, wenn das Datum eindeutig erkannt werden kann.
Dies ist bei der AS/400 eben das ISO-Format.

In VB löse ich das eben so:
if ... then
.Parameter(MyDate)="0001-01-01"
else
.Parameter(MyDate)=format(MyDate, "jjjj-mm-dd")
end if

Ich denke, für Java gibts ähnliches.