# Java & MS SQL-Datetime



## gladiator09 (27. Jan 2009)

hey leute!

hab ein programm, welches mir aus einem csv-feld ein datum ausliest und dieses will ich am MS SQL server speichern!


```
int jahr = Integer.parseInt(datum.substring(0, 3));
            int monat = Integer.parseInt(datum.substring(4, 5));
            int tag = Integer.parseInt(datum.substring(6, 7));
            GregorianCalendar calendar = new GregorianCalendar(jahr, tag, monat);
            java.sql.Date date = new java.sql.Date(calendar.getGregorianChange().getTime());
            return date;
```

das wirft mir immer eine sqlexception:  "The conversion of a char data type to a datetime data type resulted in an out-of-range datetime value."

das funktioniert:


```
int jahr = Integer.parseInt(datum.substring(0, 3));
            int monat = Integer.parseInt(datum.substring(4, 5));
            int tag = Integer.parseInt(datum.substring(6, 7));
            GregorianCalendar calendar = new GregorianCalendar(jahr, tag, monat);
            java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
            return date;
```

also mit currentTimeMillis funktionierts und mit dem Calendar nicht!

woran kann das liegen?

lg,
alex[/code]


----------



## Ebenius (27. Jan 2009)

Hinweis 1: Datum parsed man am besten mit DateFormat.parse(String) (die abgeleitete Klasse SimpleDateFormat ist auch oft nützlich).

Hinweis 2: Du hast in Zeile 4 Monat und Tag vertauscht. :lol: Da kommt bestimmt der erste Tag des Monats siebenundzwanzig raus. Und das haut Dir dann die DB um die Ohren.


----------



## gladiator09 (27. Jan 2009)

ok danke... aber das problem war auch noch: ich hab beim sql-statement die variable in einfache anführungszeichen gesetzt...

aber wenn ich jetzt mein statement änder (also so wie du gesagt hast, monat und tag austauschen), dann kommt bei einem string-wert von "20090114" in der DB das datum 16.07.1900 raus?! *gg*

bzw. habe bei monat noch 1 dazugezählt!


```
int jahr = Integer.parseInt(datum.substring(0, 3));
            int monat = Integer.parseInt(datum.substring(4, 5));
            int tag = Integer.parseInt(datum.substring(6, 7));
            GregorianCalendar calendar = new GregorianCalendar(jahr, monat+1, tag);
            java.sql.Date date = new java.sql.Date(calendar.getTime().getTime());
            return date;
```

lg,
alex


----------



## Ebenius (27. Jan 2009)

SQL-Date würde ich so ähnlich aufbauen: 
	
	
	
	





```
try {
  final java.util.Date date =
        new SimpleDateFormat("yyyyMMdd").parse("20080126");
  System.out.println(new java.sql.Date(date.getTime()));
} catch (ParseException ex) {
  ex.printStackTrace();
}
```

Wo/wie baust Du denn das Statement auf?


----------



## gladiator09 (27. Jan 2009)

ok, hab das jetzt so geschrieben wie du, bekomme aber:

Unparseable Date: "20081211"

statement:


```
s.executeUpdate("INSERT INTO sxa.Rechnungen (r_id, r_mitarbeiter, r_datum) VALUES ('" + rid + "', '" + rs.getString("m_id") + "', " + date + ")");
```

date wird an einer anderen stelle mit der oben geschriebenen methode "befüllt"

lg,
alex


----------



## thE_29 (27. Jan 2009)

Bitte bitte nehmt für Datumsoperationen IMMER PreparedStatement!

Das ist bei jeder DB und dann noch bei jeder lokalen Einstellung anders (das Datumsformat).

Nimm PreparedStatement und du hast nirgends Probleme.

Auch hier zum Nachlesen: http://www.java-forum.org/de/topic81439_prepared-statements.html (ganz unten Verweise auf XPreparedStatement)


----------



## Ebenius (27. Jan 2009)

Das Problem ist das "+ date +". Wenn Du sowas machst, brauchst Du gar kein java.sql.Date zu benutzen. 

Ansonsten schließe ich mich dem Vorredner an. Für PreparedStatements ist java.sql.Date super.


----------



## gladiator09 (27. Jan 2009)

naja, habe es jetzt so:


```
int jahr = Integer.parseInt(datum.substring(0, 3));
            int monat = Integer.parseInt(datum.substring(4, 5));
            int tag = Integer.parseInt(datum.substring(6, 7));
            GregorianCalendar calendar = new GregorianCalendar(jahr, monat+1, tag);
            //java.util.Date date = new SimpleDateFormat("yyyyMMdd").parse(datum);
            return new java.sql.Date(calendar.getTimeInMillis());
```


```
ps = cn.prepareStatement("INSERT INTO sxa.Rechnungen (r_id, r_mitarbeiter, r_datum) VALUES (?, ?, ?)");
                                    //s.executeUpdate("INSERT INTO sxa.Rechnungen (r_id, r_mitarbeiter, r_datum) VALUES ('" + rid + "', '" + rs.getString("m_id") + "', " + date + ")"); // timestamp fehlt noch
                                    ps.setString(1, rid);
                                    ps.setString(2, rs.getString("m_id"));
                                    ps.setDate(3, date);
                                    ps.execute();
```

und jetzt kommt diese exception:

com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data strea
m (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 6 ("
"): The supplied value is not a valid instance of data type datetime. Check the
source data for invalid values. An example of an invalid value is data of numeri
c type with scale greater than precision.


----------



## Ebenius (27. Jan 2009)

Du musst PreparedStatement.executeUpdate() benutzen. Geht's dann?


----------



## gladiator09 (27. Jan 2009)

ja, is mir auch aufgefallen nachdem ichs hier gepostet hab *g* funktioniert aber leider auch nicht!


----------



## Ebenius (27. Jan 2009)

Bitte gib mal den gesamten StackTrace aus. Poste Deinen entsprechenden Source-Code. Die Zeilennummern aus dem StackTrace überprüfen und mit dazuschreiben!


----------



## gladiator09 (27. Jan 2009)

com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data strea
m (TDS) remote procedure call (RPC) protocol stream is incorrect. Parameter 6 ("
"): The supplied value is not a valid instance of data type datetime. Check the
source data for invalid values. An example of an invalid value is data of numeri
c type with scale greater than precision.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError
(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown
 Source)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePrep
aredStatement(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecC
md.doExecute(Unknown Source)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(Unkno
wn Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(Unknow
n Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(Unkn
own Source)
        at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeUpdate
(Unknown Source)
        at mat.Main.egonEinlesen(Main.java:292)
        at mat.Main.main(Main.java:428)


```
try
                                {
                                    ps = cn.prepareStatement("INSERT INTO sxa.Rechnungen (r_id, r_mitarbeiter, r_datum) VALUES (?, ?, ?)");
                                    //s.executeUpdate("INSERT INTO sxa.Rechnungen (r_id, r_mitarbeiter, r_datum) VALUES ('" + rid + "', '" + rs.getString("m_id") + "', " + date + ")"); // timestamp fehlt noch
                                    ps.setString(1, rid);
                                    ps.setString(2, rs.getString("m_id"));
                                    ps.setDate(3, date);
                                    ps.executeUpdate(); // --> zeile 292
                                }
                                catch (Exception e)
                                {
                                    rid = null;
                                    e.printStackTrace();
                                }
```


```
public java.sql.Date getSQLDate(String datum)
    {
        try
        {
            int jahr = Integer.parseInt(datum.substring(0, 3));
            int monat = Integer.parseInt(datum.substring(4, 5));
            int tag = Integer.parseInt(datum.substring(6, 7));
            GregorianCalendar calendar = new GregorianCalendar(jahr, monat+1, tag);
            //java.util.Date date = new SimpleDateFormat("yyyyMMdd").parse(datum);
            return new java.sql.Date(calendar.getTimeInMillis());

        }
        catch (Exception e)
        {
            error(e);
        }

        return null;
    }
```


----------



## Ebenius (27. Jan 2009)

"data type datetime" ist doch datum und uhrzeit... Die DB will bestimmt einen Timestamp haben. PreparedStatement.setTimestamp(int, Timestamp)


----------



## gladiator09 (27. Jan 2009)

der typ vom datenfeld in der DB ist aber datetime... und das lustige daran is: wenn ich java.sql.date(System.currentTimeMillis()) returne, dann schreibt er das heutige datum einwandfrei in die datenbank


----------



## Ebenius (27. Jan 2009)

Haste's mit setTimestamp probiert? Natürlich hat's vorhin super geklappt; vorhin hast Du ja auch Strings reingeschrieben. Probier's mit setTimestamp!


----------



## gladiator09 (27. Jan 2009)

mit setTimestamp und dem date??

hab mir jetzt in der methode mal das ausgeben lassen:


```
System.out.println(System.currentTimeMillis());
            System.out.println(calendar.getTimeInMillis());
```

hat dieses hier zur folge:

1233063837714
-55853197200000

nur woran liegt das?

lg,
alex


----------



## Ebenius (27. Jan 2009)

gladiator09 hat gesagt.:
			
		

> -55853197200000


Also: "Fri Feb 01 00:00:00 CET 200"
Nimm doch das DateFormat zum Parsen!


----------



## gladiator09 (27. Jan 2009)

hab jetzt das dateformat genommen und jetzt kann ers komischerweise parsen, wo er vorher einen fehler geschrieben hat!


```
try
        {
            java.util.Date date = new SimpleDateFormat("yyyyMMdd").parse(datum);
            return new java.sql.Date(date.getTime());
        }
```

danke für eure mühe 

lg,
alex


----------

