# SQL ResultSet Previous



## jothemac (13. Sep 2012)

Hallo,

ich habe eine menge daten in einer mysql datenbank gespeichert. Nun möchte ich mit diesen berechnungen anstellen: Ich möchte den ersten eintrag nehmen und den mit dem 2 subtrahieren. Danach wieder zu eintrag 2 springen und dann eintrag 2 mit 3 subtrahieren und so weiter.... Das versuche ich so:

```
public void calculateOpeningChangeDayBefore()
    {
        try
        {
            PreparedStatement ps = dbHelper.conn.prepareStatement(
                          "SELECT DATE,OPENING FROM APP."+StockName.toUpperCase());
            ResultSet rs = ps.executeQuery();
                  
            while(rs.next())
            {
                System.out.println("OPENING DAY 1:"+rs.getString(1));
                rs.next();
                System.out.println("OPENING DAY 2:"+rs.getString(1));
                rs.previous();
            }
                  
        }
        catch(SQLException ex)
        {
            ex.printStackTrace();
            System.out.println("COULD NOT CALCULATE OPENING CHANGE DAY BEFORE");
        }
    }
```

Das Problem ist das er bei rs.previous() einen fehler meldet, aber ohne fehler ausgabe....


----------



## turtle (13. Sep 2012)

Du kannst beim Erzeugen des Statements angeben, dass Du im ResultSet scrollen möchtest.


```
conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
```


----------



## jothemac (13. Sep 2012)

Danke sehr, das hat das problem gelöst. Ich hätte da noch eine frage. Und zwar möchte ich die daten einer table für eine bestimmte column updaten. Das sieht bei mir so aus:

```
PreparedStatement ps2 = dbHelper.conn.prepareStatement(
                                  "UPDATE APP."+StockName.toUpperCase()+ 
                        "(OPENCHANGEDAYBEFORENUMBER, OPENCHANGEDAYBEFOREPERCENT,"
                            + "HIGHCHANGEDAYBEFORENUMBER, HIGHCHANGEDAYBEFOREPERCENT,"
                            + "LOWCHANGEDAYBEFORENUMBER, LOWCHANGEDAYBEFOREPERCENT,"
                            + "CLOSECHANGEDAYBEFORENUMBER, CLOSECHANGEDAYBEFOREPERCENT,"
                            + "VOLUMECHANGEDAYBEFORENUMBER, VOLUMECHANGEDAYBEFOREPERCENT,"
                            + "ADJCLOSECHANGEDAYBEFORENUMBER, ADJCLOSECHANGEDAYBEFOREPERCENT) "
                        + "VALUES("
                        +Float.valueOf(diffNumberOpening).floatValue()+","
                        +Float.valueOf(diffPercentOpening).floatValue() +","
                        +Float.valueOf(diffNumberHigh).floatValue()+","
                        +Float.valueOf(diffPercentHigh).floatValue()+","
                        +Float.valueOf(diffNumberLow).floatValue()+","
                        +Float.valueOf(diffPercentLow).floatValue() +","
                        +Float.valueOf(diffNumberClosing).floatValue()+","
                        +Float.valueOf(diffPercentClosing).floatValue()+","
                        +Float.valueOf(diffNumberVolume).floatValue()+","
                        +Float.valueOf(diffPercentVolume).floatValue()+","
                        +Float.valueOf(diffNumberAdjClose).floatValue()+","
                        +Float.valueOf(diffPercentAdjClose).floatValue()+")");
```

Jetzt würde ich gerne wissen wie ich sagen kann das das update für column 1,2... und so weiter gemacht werden soll.


----------



## nillehammer (13. Sep 2012)

Schreib in Dein Statement in die Klammern nur die Namen der Columns, die Du wirklich updaten willst und gib nur dafür Values an.

P.S. Dein Java-Code geht etwas eleganter. Statt dem hier:

```
Float.valueOf(diffNumberOpening).floatValue()
```
Schreibe das:

```
Float.parseFloat(diffNumberOpening)
```
Und die mehrfache String-Konkatenierung mit dem "+"-Operator ersetzt Du besser durch 
	
	
	
	





```
StringBuilder.append
```
:

```
StringBuilder statementStr = new StringBuilder();
statementStr.append("UPDATE APP.").append(StockName.toUpperCase())
// usw.
dbHelper.conn.prepareStatement(statementStr.toString());
```


----------



## jothemac (13. Sep 2012)

Die columns haben keinen Namen(max datum), ich würde es gerne so machen:
Update daten xy in column der reihe(also dessen platzt in der Tabelle) xy der tabelle xx.


----------



## nillehammer (13. Sep 2012)

> Die columns haben keinen Namen


Das gibt es nicht. UPDATES kannst Du nur auf Tabellen machen. Dort hat jede Column einen Namen.


> Update daten xy in column der reihe(also dessen platzt in der Tabelle) xy der tabelle xx.


In SQL-Updatestatements gibt es sowas wie Spaltenindizes nicht. Du könntest aber die Angabe von Spaltennamen umgehen, indem Du die Klammern mit den Columnnames komplett weglässt und bei Values Werte für *alle* Spalten angibst. Die, die verändert werden sollen, enthalten neue Werte. Die die gleich bleiben sollen, enthalten die Werte, die schon drinnen stehen. Die Reihe wählst Du über eine entsprechende WHERE-Klausel aus.


----------



## jothemac (13. Sep 2012)

Ok danke für die aufklärung, dann werde ich die columns über das datum ansprechen.


----------



## jothemac (13. Sep 2012)

Müsste das ganze nicht ungefähr so aussehen?


```
PreparedStatement ps2 = dbHelper.conn.prepareStatement(""
                                + "UPDATE APP."+StockName.toUpperCase()+
                                " SET OPENCHANGEDAYBEFORENUMBER = ?, SET OPENCHANGEDAYBEFOREPERCENT = ?"
                                +"SET HIGHCHANGEDAYBEFORENUMBER = ?, SET HIGHCHANGEDAYBEFOREPERCENT = ?,"
                                +"SET LOWCHANGEDAYBEFORENUMBER = ?, SET LOWCHANGEDAYBEFOREPERCENT = ?,"
                                +"SET CLOSECHANGEDAYBEFORENUMBER = ?, SET CLOSECHANGEDAYBEFOREPERCENT = ?,"
                                +"SET VOLUMECHANGEDAYBEFORENUMBER = ?, SET VOLUMECHANGEDAYBEFOREPERCENT = ?"
                                +"SET ADJCLOSECHANGEDAYBEFORENUMBER = ?, SET ADJCLOSECHANGEDAYBEFOREPERCENT = ?"
                                +" WHERE DATE = ?");
                        ps2.setFloat(1, diffNumberOpening);
                        ps2.setFloat(2, diffPercentOpening);
                        ps2.setFloat(3, diffNumberHigh);
                        ps2.setFloat(4, diffPercentHigh);
                        ps2.setFloat(5, diffNumberLow);
                        ps2.setFloat(6, diffPercentLow);
                        ps2.setFloat(7, diffNumberClosing);
                        ps2.setFloat(8, diffPercentClosing);
                        ps2.setFloat(9, diffNumberVolume);
                        ps2.setFloat(10, diffPercentVolume);
                        ps2.setFloat(11, diffNumberAdjClose);
                        ps2.setFloat(12, diffPercentAdjClose);
                        ps2.setString(13, date);
```


----------



## nillehammer (14. Sep 2012)

Sieht gut aus.

In Deinen vorherigen Posts waren die ganzen Variablen 
	
	
	
	





```
diffNumberOpening etc.
```
 noch Strings, die Du erst nach 
	
	
	
	





```
float
```
 geparst hast. Ich nehme an, dass Du das inzwischen so geändert hast, dass diese Variablen jetzt schon vom Typ 
	
	
	
	





```
float
```
 sind? Denn sonst würde Dein Code ja nicht kompilieren.

Und das hier:
[JAVA=22]
ps2.setString(13, date);
[/code]
sieht mir auch noch etwas verdächtig aus. Das geht nur, wenn 1. 
	
	
	
	





```
date
```
 vom Typ String ist und 2. in der Datenbanktabelle die entspr. Column vom Typ VARCHAR ist. Sollte sie ein Date-Typ sein, müsstest Du mit java.sql.Date und der entspr. setDate-Methode des PreparedStatement arbeiten.


----------



## jothemac (14. Sep 2012)

SO ich habe es jetzt hinbekommen und zwar so:

```
try
                    {
                        
                        PreparedStatement ps2 = dbHelper.conn.prepareStatement(""
                                + "UPDATE APP."+StockName.toUpperCase()
                                +" SET OPENCHANGEDAYBEFORENUMBER = ? , OPENCHANGEDAYBEFOREPERCENT = ?,"
                                +"  HIGHCHANGEDAYBEFORENUMBER = ?,  HIGHCHANGEDAYBEFOREPERCENT = ?,"
                                +"  LOWCHANGEDAYBEFORENUMBER = ?,  LOWCHANGEDAYBEFOREPERCENT = ?,"
                                +"  CLOSECHANGEDAYBEFORENUMBER = ?,  CLOSECHANGEDAYBEFOREPERCENT = ?,"
                                +"  VOLUMECHANGEDAYBEFORENUMBER = ?,  VOLUMECHANGEDAYBEFOREPERCENT = ?,"
                                +"  ADJCLOSECHANGEDAYBEFORENUMBER = ?,  ADJCLOSECHANGEDAYBEFOREPERCENT = ?"
                                +" WHERE DATE = ?");
                        ps2.setDouble(1, Float.valueOf(diffNumberOpening).floatValue());
                        ps2.setDouble(2, Float.valueOf(diffPercentOpening).floatValue());
                        ps2.setDouble(3, Float.valueOf(diffNumberHigh).floatValue());
                        ps2.setDouble(4, Float.valueOf(diffPercentHigh).floatValue());
                        ps2.setDouble(5, Float.valueOf(diffNumberLow).floatValue());
                        ps2.setDouble(6, Float.valueOf(diffPercentLow).floatValue());
                        ps2.setDouble(7, Float.valueOf(diffNumberClosing).floatValue());
                        ps2.setDouble(8, Float.valueOf(diffPercentClosing).floatValue());
                        ps2.setDouble(9, Float.valueOf(diffNumberVolume).floatValue());
                        ps2.setDouble(10, Float.valueOf(diffPercentVolume).floatValue());
                        ps2.setDouble(11, Float.valueOf(diffNumberAdjClose).floatValue());
                        ps2.setDouble(12, Float.valueOf(diffPercentAdjClose));
                        ps2.setString(13, dateTemp);
                    }
                    catch(SQLException ex)
                    {
                        ex.printStackTrace();
                    }
```

Wichtig ist: das agrument SET nicht wiederholen! Das habe ich öfter im inet gesehen. Nun ist etwas komisches passiert. Die berechnungen sind richtig, das habe ich über die konsole nach geschaut. Nur wenn ich die werte nun wieder aus der datenbank auslesen möchte, sind sie 11 von 10 null, und der 11 Eintrag ist vollkommen verkehrt. Irgendwie geht da was verloren, oder eher beim schreiben was schief. Ja alle variablen(bis auf dateTemp), sind Float variablen, die Tabelle erwartet für die einträge den mySQL-Typ DOUBLE.

Etwas peinlich aber: ich habe einfach den verkerten query genutzt:

```
ps2.executeUpdate();
```

Damit geht's


----------



## nillehammer (14. Sep 2012)

Ja, das mit den diversen SETs hatte ich auch so gefunden. Gut, dass Du rausgefunden hast, dass man das garnicht braucht bzw., dass es sogar schlicht falsch ist.

Bei den Datentypen musst Du aber -glaube ich- noch sauberer arbeiten.




> Ja alle variablen(bis auf dateTemp), sind Float variablen,


Dein Code sagt hier was anderes. Wenn die Variablen schon vom typ 
	
	
	
	





```
float
```
 wären, müsstest du ja nicht die ganzen valueOf-Aufrufe machen.
Wie schon in einem meiner letzten Posts geschrieben, kannst Du mit parseFloat(...) Deinen Code verkürzen.
Du verwendest 
	
	
	
	





```
ps.setDouble
```
, weil die Spalten den mySql-Typ Double haben. Dann solltest Du auch doubles übergeben mit 
	
	
	
	





```
Double.parseDouble(...)
```
.



> Nur wenn ich die werte nun wieder aus der datenbank auslesen möchte, sind sie 11 von 10 null,


Nur eine Spekulation, aber vielleicht fehlt hier ein Commit. Entweder in Form der autoCommit-Einstellung beim Erzeugen der Connection oder durch expliziten Aufruf von commit() auf dem Connection-Objekt.
[EDIT]Ok, der letze Punkt hatte eine andere Ursache...[/EDIT]


----------

