Geändertes ResultSet zurück schreiben

Hallo,

seit einigen Tagen habe ich mit einem sehr merkwürdigen Problem zu tun. Leider komme ich auch mit Hilfe der Suchefunktion und dem Web nicht weiter. Vielleicht hat jemand von Euch noch eine Idee und kann mir helfen.

Ich öffne eine MS-SQL Db per jdbc, erzeuge ein Statement und führe es aus.
Das korrekte Ergebins steht in einem ResultSet.

Jetzt möchte ich einige Daten ändern und zurückschreiben, also sieht das Satement so aus:

ResultSet rs = stmt.executeQuery(sqlQuery); 
String name=rs.getString("name","hallo");        // das DB-Feld Name soll den Wert hallo bekommen
rs.updateString("name",name);       
rs.updateRow();

Welche weiteren Voraussetzungen sind erforderlich, damit die Daten auch tatsächlich zurückgeschrieben werden. Ich den Danke

Hi,

frt DB-Cursor steht nach einem executeQuery() auf „befor-first“. Du musst einmal „rs.next()“ aufrufen, um eine Zeile darin zu ändern.

Gruß,

Martin

geht es denn bisher nicht? was genau funktioniert alles, welche Fehlermeldungen usw.,

kein Beispiel vorher angeschaut?
http://docs.oracle.com/javase/tutorial/jdbc/basics/retrieving.html

String name=rs.getString("name","hallo"); // das DB-Feld Name soll den Wert hallo bekommen
ist doch undenkbarer Aufbau, get kann nur abfragen, in der Zeile danach hättest du die ideale Möglichkeit, “hallo” zu speichern,
so elementare Dinge wie holen + setzen schon zu schwer zu durchblicken?

bevor nicht next() aufgerufen wird, kann sowieso gar nichts machen, keine Row im ResultSet ausgewählt

Zeile 3 ist doch falsch? rs.getString hat nur einen Parameter (int oder String)

welchen Grund gibt es, nicht ein SQL-UPDATE zu verwenden

und zum Thema: gibt es einen Primärschlüssel? wie sieht die Tabelle aus? auto-commit eingeschaltet? wie sieht die Query aus? hoffentlich keine View?

sorry, das getString() ist natürlich ein updateString()
autoCommit ist an,
die Query lautet: select cnr,name,rechner,os,cnormdelay,cshortdelay,startpkt,endpkt,dauer,pausenlen,lebt_noch,servstat,sstat_seit from comserver where cnr = 1
… also nichts besonderes und es ist auch kein view.
Nach dem Ausführen der Query positioniere ich auf dem ersten Satz mit rs.first() und lese die Daten mit getString(), getInt usw. in die Properties des objekts.

Aber vielleicht muss ich weiter ausholen :
ich habe mir eine Klasse gemacht, die Tabellen aus der DB abbildet:


    protected ResultSet rs;
    private String sqlQuery;
    private Database db;
    private int recCount = 0;
    private int position = -1;

    public Table(String query) {
        db = G32.getInstance();
        sqlQuery = query.trim();
    }

    public void commit() {
        try {
            if (!G32.conn.getAutoCommit()) {
                G32.conn.commit();
            }
        } catch (SQLException ex) {
            Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void rollback() {
        try {

            if (!G32.conn.getAutoCommit()) {
                G32.conn.rollback();
            }
        } catch (SQLException ex) {
            Logger.getLogger(Table.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    // muss von der Ableitung überschrieben werden
    public boolean get() {
        return false;
    }

    // muss von der Ableitung überschrieben werden
    public boolean update() {
        return false;
    }

    // muss von der Ableitung überschrieben werden
    public void initInsertRow()
    {
   
    }

    public boolean scatter() {
        return get();
    }

    public boolean gather() {

        if (update()) {
            try {
                rs.updateRow();
                return true;
            } catch (SQLException ex) {
                String message = ex.getMessage();
                Logger
                        .getLogger(Database.class
                        .getName()).log(Level.SEVERE, null, ex);
                Logger.getLogger(
                        "").info(message);


                return false;
            }
        } else {
            return false;
        }

    }


    public int append() {
        try {
            initInsertRow();
            return 0;
        } catch (SQLException ex) {
            String message = ex.getMessage();
            Logger
                    .getLogger(Database.class
                    .getName()).log(Level.SEVERE, null, ex);
            Logger.getLogger(
                    "").info(message);
        }
        return 0;
    }

    public int load() {
        try {
            Statement stmt = Database.conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE );
            rs = stmt.executeQuery(sqlQuery);                 // Statement ausführen

            rs.last();
            recCount = rs.getRow();

            if (recCount > 0) {
                rs.first();
                position = rs.getRow();
                if (!scatter()) {
                    position = 0;
                }
            } else {
                position = 0;
            }

        } catch (SQLException ex) {
            String message = ex.getMessage();
            Logger
                    .getLogger(Database.class
                    .getName()).log(Level.SEVERE, null, ex);
            Logger.getLogger(
                    "").info(message);


            return -1;

        }
        return position;
    }
}```
Je Tabelle, die ich benutzen möchte, mache ich eine Ableitung wie hier:
```public class Comserver extends Table {

    public int cnr;                 
    public String name;          
    public String rechner;       
    public String os;                  
    public int normdelay;        
    public int shortdelay;        
    public LocalTime startZeitpunkt; 
    public LocalTime endZeitpunkt;   
    public int dauer;            
    public int pausenlen;    
    public Timestamp lebtNoch; 
    public int servStat;             
    public Timestamp sstat_seit; 

    public Comserver(String query) {
        super(query);
    }

    public void setState(int state) {
        Timestamp jetzt = new Timestamp(System.currentTimeMillis());
        servStat = state;
        sstat_seit = jetzt;
        gather();
        commit();
    }

    public void weiterleben(Timestamp bisdann) {
        lebtNoch = bisdann;
        gather();       
        commit();
    }

    @Override
    public boolean get() {
        try {
            cnr = rs.getInt("cnr");
            name = rs.getString("name");
            rechner = rs.getString("rechner");
            os = rs.getString("os");
            normdelay = rs.getInt("cnormdelay");            // in 1/10 Sek.
            shortdelay = rs.getInt("cshortdelay");          // in 1/10 Sek.
            startZeitpunkt = LocalTime.parse(rs.getString("startpkt") + ":00");
            endZeitpunkt = LocalTime.parse(rs.getString("endpkt") + ":59");
            dauer = rs.getInt("dauer");
            pausenlen = rs.getInt("pausenlen");
            lebtNoch = rs.getTimestamp("lebt_noch");
            servStat = rs.getInt("servstat");
            sstat_seit = rs.getTimestamp("sstat_seit");
        } catch (SQLException ex) {
            String message = ex.getMessage();
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
            Logger.getLogger("").info(message);
            return false;
        }
        return true;
    }

    @Override
    public boolean update() {
        try {
            //    rs.updateInt("cnr",cnr);             Primary Key mit Autoinc kann  man nicht zurückschreiben          
            rs.updateString("name", name);
            rs.updateString("rechner", rechner);
            rs.updateString("os", os);
            rs.updateInt("cnormdelay", normdelay);
            rs.updateInt("cshortdelay", shortdelay);
            rs.updateInt("dauer", dauer);
            rs.updateInt("pausenlen", pausenlen);
            rs.updateTimestamp("lebt_noch", lebtNoch);
            rs.updateInt("servstat", servStat);
            rs.updateTimestamp("sstat_seit", sstat_seit);

        } catch (SQLException ex) {
            String message = ex.getMessage();
            Logger.getLogger(Database.class.getName()).log(Level.SEVERE, null, ex);
            Logger.getLogger("").info(message);
            return false;
        }
        return true;
    }
}

benutzen wollte ich es im Prinzip so:

            comserver.load();
            comserver.os = System.getProperty("os.name") + " Version " + System.getProperty("os.version");
            comserver.gather()

Danke
Peter

jetzt habe ich wohl irgendwie alle verschreckt - oder ist mein Ansatz einfach zu blöd ??

Rufst du den jetzt next() auf vor dem Update?

Doch da scheint „first“ auferufen zu werden. Aber ist das möglich in einem Scroll Set, wenn man vorher Last aufgerufen hat?

Versuch das mal an einen minimalen Beispiel.

Ich positioniere also nur einmal am Anfang:erst auf last um die Anzahl der Sätze zu ermitteln und dann auf first um auf den für mich interessanten Satz zu positionieren (in meinen Versuchen arbeite ich Satz 1).
Im Moment sieht es so aus, als wenn das Schreiben nur genau einmal funktioniert. alle folgenden Änderunegn auf dem ResultSet kommen nicht in der DB an. So wie ich die Doku lese, müsste UpdateRow() den Satz eigentlich schreiben …

Ich kann das gerade hier mangels Entwicklerumgebung nicht nachvollziehen.

Hast du es schon mit einem Minimalen Beispielprobiert?

Ich kann mir vorstellen, dass du hier mit den Referenzen etwas durcheinander kommst.

in einem Minimalbeispiel kann ich mehrmals den Satz ändern und erfolgreich zurückschreiben.
Kannst Du in meiner Ableitung und Override von Table/Comserver einen Fehler entdecken? Im Moment seh ich den Wald vor laueter Bäumen nicht…