MySQL SQL Abfrage erneut ausführen oder rs aktualisieren

nonickatall

Mitglied
Hallo ich habe eine Klasse die auf einem MySQL Server nach neuen Einträgen in einer Tabelle sucht. Das Ganze will ich in einem While() laufen lassen um permanent zu pollen.

Jedoch ist das Problem, dass das einmal gebildete Objekt und das ResultSet beim nächsten Durchlauf nicht aktualisiert werden, obwohl der in Hintergrund gelöschte Datensatz gar nicht mehr existiert. Nehme ich den loop für Testzwecke raus, dann ist beim nächsten Start alles wie es sein soll.

Ich kann ja nicht bei jedem Lauf die Objektvariable hochzählen. Gibt es eine Möglichkeit das Objekt s oder das ResultSet rs so zu killen, damit es beim nächsten Durchlauf erneut erzeugt wird?

s = null; oder rs = null; bewirken nichts.

Java:
package myhome;

import java.sql.*;
import java.util.Arrays;

public class Eventmgr {
    private static boolean loop = false;
    private static int loop_count = 2;
    private static String in_id;
    private static String in_nummer;
    private static String in_text;
    private static String in_typ;
    
    public static void start() throws SQLException {
        
        //Verbindung zum SQL-Server herstellen
        
        while(loop_count > 0) {
            //Loop an oder aus für Testzwecke
            if (loop == false) {
                loop_count = loop_count -1;}
            
            //SQL Neue Datensätze holen   
            SQL s = new SQL();             
            s.connect();
            ResultSet rs = s.abfrage("select id, nummer, text, typ from inbox order by id asc limit 1") ;
            while(rs.next()) {
                in_id = rs.getString("id");
                in_nummer = rs.getString("nummer");
                in_text = rs.getString("text");
                in_typ = rs.getString("typ");}
            s.close();
            System.out.println(in_nummer);
            
            // [Entscheiden welche Art Datensatz es ist]
            if (in_typ != null) {
                if (in_typ.contains("SMS")) {
                    //SMS:
                    //Prüfen ob der Berechtigte existiert, der oder die Befehle gültig sind und die Rechte dazu existieren.
                    Befehle.extrahieren(in_id, in_nummer, in_text);}   
        
                else if (in_typ.contains("intern")) {
                    //intern
                    Befehle.extrahieren(in_id, in_text);}   
        
                else if (in_typ.contains("@")) {
                    //@Befehl@
                    Befehle.extrahieren_lang(in_id, in_nummer, in_text);}
                }
            
            //rs = null;
            System.out.println(s);
            }
    }
}

Vielen Dank im Voraus

Ralf
 
Ich würde die DB Connection vor der Schleife machen und am ende wieder zumachen.
Die Abfrage (und das Result Set) in der Schleife.

Zum schliessen den RS gibt es: close()
 
Durch die Verwendung Deiner SQL-Klasse kann man wenig sagen. Jedenfalls musst Du das ResultSet und das Statement schließen.
 
Danke für die Antworten.

Habe beides probiert bringt aber nichts. Habe die Klasse SQL mal übergangen und direkt implementiert. Vielleicht habt Ihr noch eine Idee woran es liegen kann?

Java:
package myhome;

import java.sql.*;

public class Eventmgr {
    private static boolean loop = true;
    private static int loop_count = 2;
    private static String in_id;
    private static String in_nummer;
    private static String in_text;
    private static String in_typ;
    
    private static Connection connection;
    
    private static String URL = "jdbc:mysql://xxx.xxx.x.x:3306/myhome";
    private static String username = "xxxxx";
    private static String password = "xxxxx";
        
    public static void start() throws SQLException {
        
        //Verbindung zum SQL-Server herstellen
        while(loop_count > 0) {
            //Loop an oder aus für Testzwecke
            if (loop == false) {
                loop_count = loop_count -1;}
        
            
            //SQL Neue Datensätze holen   
            SQL s = new SQL();             
            connection = DriverManager.getConnection(URL, username, password);
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery("select id, nummer, text, typ from inbox order by id asc limit 1") ;
            while(rs.next()) {
                in_id = rs.getString("id");
                in_nummer = rs.getString("nummer");
                in_text = rs.getString("text");
                in_typ = rs.getString("typ");}
            connection.close();
            stmt = null;
            rs.close();
            System.out.println("Loop läuft");

            
            // [Entscheiden welche Art Datensatz es ist]
            if (in_typ != null) {
                if (in_typ.contains("SMS")) {
                    //SMS:
                    //Prüfen ob der Berechtigte existiert, der oder die Befehle gültig sind und die Rechte dazu existieren.
                    Befehle.extrahieren(in_id, in_nummer, in_text);}   
        
                else if (in_typ.contains("intern")) {
                    //intern
                    Befehle.extrahieren(in_id, in_text);}   
        
                else if (in_typ.contains("@")) {
                    //@Befehl@
                    Befehle.extrahieren_lang(in_id, in_nummer, in_text);}
                }
            
            //s = null;
            //rs = null;
            System.out.println(s);
            }
        }
}
 
Wieso baust du jedes mal in der Schleife die Verbindung auf?

Java:
SQL s = new SQL();             
connection = DriverManager.getConnection(URL, username, password);
Statement stmt = connection.createStatement();
while(loop_count > 0) {
    ResultSet rs = stmt.executeQuery("select id, nummer, text, typ from inbox order by id asc limit 1") ;
    ...
    rs.close();
}
stmt.close();
connection.close();
 
Wie kommst Du eigentlich darauf, dass der Datensatz "zwischenzeitlich" gelöscht sein müsste?
Weil ich polle, dann eine Methode in einer Klasse aufrufe, die den Datensatz bearbeitet und zum Schluß löscht. Das funktioniert auch, aber die Schleife vergisst leider nicht...

Starte ich aber neu, ist alles wie es sein soll, bis ich im Hintergrund, von einen anderen Client, wieder einen Datensatz in die Tabelle "schiebe".
 
Wieso baust du jedes mal in der Schleife die Verbindung auf?

Java:
SQL s = new SQL();            
connection = DriverManager.getConnection(URL, username, password);
Statement stmt = connection.createStatement();
while(loop_count > 0) {
    ResultSet rs = stmt.executeQuery("select id, nummer, text, typ from inbox order by id asc limit 1") ;
    ...
    rs.close();
}
stmt.close();
connection.close();
Weil ich gerade herum teste, wie ich das Problem weg bekomme. ;-)
Hatte am Anfang die Connection vor der Schleife. War kein Unterschied.
 
Verstehe, habe die Reihenfolge geändert.

Ich bin ein totaler Depp... Und habe Euch auf eine völlig falsche Fährte geführt. 😳 Liegt wohl daran weil das mein erstes Programm in Java ist und ich noch mit all dem Wissen kämpfe.

Ich prüfe natürlich auf die Variable "in_typ". Wenn die nicht neu gesetzt wird, weil "while(rs.next()){" keinen neuen Datensatz liefert, bleibt natürlich das Ergebnis gleich. Das hatte nichts mit dem ResultSet zu tun...

Ich habe die Variablen am Ende der Schleife nun mit "in_typ = null;" usw. zurück gesetzt. Nun geht es.

@mihe7
Zu dem Thema static...

An welcher Stelle meinst du? Ich kämpfe da noch mit dem Verständnis von static und non static...

Trotzdem vielen Dank an Euch beide für die Hilfe..

LG
Ralf
 
Zuletzt bearbeitet:
Aber in diesem Zusammenhang mal eine andere Frage zum grundsätzlichen Verständnis.

Wenn ich eine statische Klasse aufrufe:

Java:
Befehle.extrahieren(in_id, in_nummer, in_text);

wo ich wiederum eine Connection mit Hilfe einen Objektes zum SQL Server

Java:
SQL s3 =  new SQL();

mache, die was abarbeitet z.B.

Java:
        //User ermitteln
        System.out.println("User ermitteln" );
        SQL s3 = new SQL();
        s3.connect();
        ResultSet rs3 = s3.abfrage("SELECT berechtigter, id from berechtigte WHERE nummer = '" + in_nummer + "'");
        while(rs3.next()) {
            berechtigte_id = rs3.getString("id");
            berechtigte_berechtigter = rs3.getString("berechtigter");}
        s3.close();

und die statische Klasse "Befehle" sich nach Abarbeitung aller Methoden sich selbst automatisch beendet, wenn ich das richtig verstanden habe? Dann habe ich ja die Connection "s3" mit
Java:
s3.close();
bereits wieder beendet. Das ist aus meinem derzeitigen Verständnis deswegen notwendig, weil der MySql Server sonst verwaiste Verbindungen offen hält. Oder?

Aber was ist mit dem Statement "stm" in der Klasse SQL und dem "ResultSet rs3"? Stirbt das automatisch mit, oder muss ich die immer manuell schließen? Denn das sind doch im Grunde Variablen, bzw. Instanzvariablen der Klasse Befehle, bzw. des Objektes s3.

Oder liege ich da falsch?

Vielen Dank im Voraus für Erhellung..
 
Ich prüfe natürlich auf die Variable "in_typ". Wenn die nicht neu gesetzt wird, weil "while(rs.next()){" keinen neuen Datensatz liefert, bleibt natürlich das Ergebnis gleich.
Ah, das hätte ich eigentlich sehen müssen. Ärgerlich.

@mihe7
Zu dem Thema static...

An welcher Stelle meinst du?
Überall, außer bei main, ggf. inneren Typen und Konstanten (static final).

static dient dazu, Variablen, Konstanten, Typen und Methoden zu definieren, die für die Gesamtheit aller Objekte (sprich: die Klasse der Objekte) gelten.
  • Eine statische Variable ist nichts anderes als ein globaler, veränderlicher Zustand; etwas, das man wirklich nicht will.
  • Eine Konstante ist etwas, das man ggf. global im Zugriff haben will. Da sich die Konstante aber nicht ändert, ist das auch in Ordnung.
  • Statische innere Typen sind ok. Sie stellen keinen Zustand dar.
  • Statische Methoden können nur auf statische Variablen/Konstanten zugreifen. Da man statische Variablen nicht möchte, ist ihr Einsatz im Wesentlichen darauf beschränkt, reine Funktionen zu definieren.
  • main muss statisch sein. Die JVM nutzt die Methode als Programmeinstiegspunkt, ohne ein Objekt erzeugen zu müssen.
Auf den neuen Kommentar gehe ich gleich nochmal separat ein, der hat nämlich nichts mit static zu tun 🙂
 
So, jetzt hat es ein wenig gedauert, nachdem ich hier unterbrochen wurde.

Aber was ist mit dem Statement "stm" in der klasse SQL und dem "ResultSet rs3"? Stirbt das automatisch mit, oder muss ich die immer manuell schließen? Denn das sind doch im Grunde Variablen, bzw. Instanzvariablen der Klasse Befehle, bzw. des Objektes s3.

Oder liege ich da falsch?
Da liegst Du (nicht ganz) falsch. Die Objekte beschreiben in der Regel Ressourcen des SQL-Servers. Es ist nicht so, dass das Connection-Objekt darüber Buch führen müsste, welche Statements Du erzeugen lässt, um automatisch ein close() auszuführen. Die Ressource gibt der SQL-Server spätestens frei, wenn die Verbindung geschlossen wird. Das ist aber kein sauberes Vorgehen und kann durchaus zu Problemen führen, insbesondere, wenn Du mit einer Verbindung viele Statements öffnest. Wenn allerdings ein Objekt in Java Buch führt, dann bekommst Du ein schönes Memory Leak, weil das Objekt vom Garbage Collector nicht abgeräumt werden kann (wenn der Treiber sauber programmiert ist, sollte er dann implizit ein close() ausführen).

Kurz: schließe, was Du geöffnet hast und zwar in umgekehrter Reihenfolge.
 

Zurück
Oben