zwei Strings vergleichen

chrism120

Aktives Mitglied
Hallo ich habe ein funKtion insertdb () gemacht und die funktioniert einwandfrei. Aber ich will diesmal bevor ich die Daten in die Datenbank einfüge , möchte ich 2 Strings vergleichen. ob die Daten schon existieren einfach weiter. könnt ihr bitte einen Blick darauf werfen und mir bescheid sagen was ich falsch gemacht habe?
Unter ist meine Code
Java:
    if (ad.isReachable(timeout)) {
                 try
                          {
                          Statment stat=conn.createStatement();
                         Resultset resultat=stat.executeQuery("SELECT HostName from Adresse ");
                          while (resultat.next()) {
                          String HostName = resultat.getString(2);
                            String adresse = ad.getHostName();
                            count(a);
                         if (HostName.equals(adresse)) {
                                 System.out.println("OK count" + adresse);
                                break;
                                                     }
                             else {
                insertdb("INSERT INTO Adresse (Ip,HostName,ThreadNummer) VALUES (?,?,?)", s, ad.getHostName(), 2);
                        count(a);
                            }
                    }
                } catch (SQLException e)
               {
                                    e.printStackTrace();
                    }
    }
Danke Im Voraus für Ihre Antwort
 
K

kneitzel

Gast
Also statt da durch alle Daten durch zu gehen kann man doch einfach gezielt nach dem Datensatz schauen, also ein SELECT HostName from Adresse where HostName = ?.

Ansonsten scheint das getString(2) falsch zu sein, denn Du fragst ja nur den HostName ab und sonst nichts. Es kommt also nur eine Spalte zurück.

Und dann ist auch die Logik falsch: Du bekommst also mehrere Datensätze.
Nun prüfst Du im ersten Datensatz: Ist der HostName der gesuchte? Nein -> INSERT
Dann der zweite Datensatz; Ist der der Hostname der gesuchte? Nein -> INSERT
Der dritte Datensatz ist dann der richtig - fein - aber Du hast schon zwei mal ein INSERT gemacht ...
 

mihe7

Top Contributor
Man kann die Duplikatsprüfung auch gleich der DB überlassen, z. B.
SQL:
INSERT INTO Adresse(Ip, HostName, ThreadNummer) 
  SELECT ?, ?, ? FROM (SELECT 1) x
   WHERE NOT EXISTS (SELECT 1 FROM Adressen WHERE HostName=?);

Bei
SQL:
INSERT INTO Adresse(Ip, HostName, ThreadNummer) 
  SELECT ?, x.Hostname, ? FROM (SELECT ? as Hostname) x
   WHERE NOT EXISTS (SELECT 1 FROM Adressen WHERE HostName=x.Hostname);
bin ich mir nicht ganz sicher, könnte aber auch funktionieren. Dann bräuchte man den Hostnamen nur einmal anzugeben.
 

chrism120

Aktives Mitglied
Also statt da durch alle Daten durch zu gehen kann man doch einfach gezielt nach dem Datensatz schauen, also ein SELECT HostName from Adresse where HostName = ?.

Ansonsten scheint das getString(2) falsch zu sein, denn Du fragst ja nur den HostName ab und sonst nichts. Es kommt also nur eine Spalte zurück.

Und dann ist auch die Logik falsch: Du bekommst also mehrere Datensätze.
Nun prüfst Du im ersten Datensatz: Ist der HostName der gesuchte? Nein -> INSERT
Dann der zweite Datensatz; Ist der der Hostname der gesuchte? Nein -> INSERT
Der dritte Datensatz ist dann der richtig - fein - aber Du hast schon zwei mal ein INSERT gemacht ...
ich verstehe nicht ganz genau was Du meinst. Kanst Du bitte es modeliren ?
 

chrism120

Aktives Mitglied
Man kann die Duplikatsprüfung auch gleich der DB überlassen, z. B.
SQL:
INSERT INTO Adresse(Ip, HostName, ThreadNummer)
  SELECT ?, ?, ? FROM (SELECT 1) x
   WHERE NOT EXISTS (SELECT 1 FROM Adressen WHERE HostName=?);

Bei
SQL:
INSERT INTO Adresse(Ip, HostName, ThreadNummer)
  SELECT ?, x.Hostname, ? FROM (SELECT ? as Hostname) x
   WHERE NOT EXISTS (SELECT 1 FROM Adressen WHERE HostName=x.Hostname);
bin ich mir nicht ganz sicher, könnte aber auch funktionieren. Dann bräuchte man den Hostnamen nur einmal anzugeben.
ich hatte es den Ansatz ausprobiert und habe kein gutes Resultat erhalten
 

mihe7

Top Contributor
Genauer, bitte. Ich gehe mal davon aus, dass Du meinen Tippfehler bei den Tabellennamen (Adressen statt Adresse) gesehen und korrigiert hast. Den Hostnamen musst Du in der ersten Variante für den 2. und 4. Parameter setzen, in der zweiten Variante wäre es dagegen nur der 3.
 

mihe7

Top Contributor
Hier mal ein Beispiel, mit MySQL getestet:
Java:
import java.sql.*;

public class Test {
    public static void main(String[] args) throws Exception {
        try(Connection conn = DriverManager.getConnection(args[0], args[1], args[2])) {
            createTable(conn);
            delete(conn, "127.0.0.1");
            insert(conn, "127.0.0.1", "localhost", Thread.currentThread().getId());
            insert(conn, "127.0.0.1", "localhost", Thread.currentThread().getId());        
        }
    }

    private static void createTable(Connection conn) {
        try(Statement stmt = conn.createStatement()) {
            stmt.execute("CREATE TABLE Adresse(ip varchar(20) not null primary key, " +
                         "HostName varchar(255) not null, " +
                         "ThreadNummer BIGINT not null);");         
        } catch (SQLException ex) {
            System.err.println("createTable: " + ex.getLocalizedMessage());
        }
    }

    private static void delete(Connection conn, String ip) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "DELETE FROM Adresse WHERE ip=?")) {
            stmt.setString(1, ip);
            int rowsDeleted = stmt.executeUpdate();
            System.out.printf("%d rows deleted.\n", rowsDeleted);
        }
    }

    private static void insert(Connection conn, String ip, String host, long thread) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "INSERT INTO Adresse(ip, HostName, ThreadNummer) " +
                "SELECT ?, ?, ? FROM (SELECT 1) x " +
                " WHERE NOT EXISTS (SELECT 1 FROM Adresse WHERE HostName = ?)")) {
            stmt.setString(1, ip);
            stmt.setString(2, host);
            stmt.setLong(3, thread);
            stmt.setString(4, host);

            int rowsInserted = stmt.executeUpdate();
            System.out.printf("%d rows inserted.\n", rowsInserted);
        }
    }
 
}

Bei einer Oracle DB müsstest Du "(SELECT 1) x" vermutlich durch "DUAL" ersetzen.

Auch die zweite Variante
Java:
    private static void insert(Connection conn, String ip, String host, long thread) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "INSERT INTO Adresse(ip, HostName, ThreadNummer) " +
                "SELECT ?, x.host, ? FROM (SELECT ? AS host) x " +
                " WHERE NOT EXISTS (SELECT 1 FROM Adresse WHERE HostName = x.host)")) {
            stmt.setString(1, ip);
            stmt.setLong(2, thread);
            stmt.setString(3, host);

            int rowsInserted = stmt.executeUpdate();
            System.out.printf("%d rows inserted.\n", rowsInserted);
        }
    }
funktioniert.
 
K

kneitzel

Gast
ich verstehe nicht ganz genau was Du meinst. Kanst Du bitte es modeliren ?
Also ich hatte mehrere Punkte angesprochen. Bitte konkret sagen, was Du genauer haben willst.

Der erste Punkt war eine Lösung, bei dem Du entweder einen oder keinen Datensatz zurück bekommst. Die Abfrage muss dann halt wie folgt aussehen:
SELECT HostName from Adresse where HostName = ?
Aufzubauen wäre dann die Abfrage selbst über ein PreparedStament ähnlich wie bei Deinem INSERT. (Zumindest gehe ich davon aus, dass Du das dort verwendet hast.)

Der zweite Punkt ist ein Fehler beim Auslesen des ResultSets. getString(2) gibt den Wert aus der zweiten Spalte. Aber Du hast nur eine Spalte (HostName).

Der dritte Punkt, ist der Logik-Fehler: Wenn Du in einer Schleife ein if/else hast, dann wird für jeden Wert in der Schleife entweder der if Part oder der else Part ausgeführt. Also wenn die ersten x Datensätze in das else laufen, dann hast Du das x mal ausgeführt ....

Ansonsten gefällt mir die Lösung von mihe7 sehr gut. Hier wäre aber noch die Frage, welche Datenbank Du genau verwendest. Einige haben dafür auch spezielle Lösungen (mysql/mariadb z.B.), die eben nicht Standard SQL sind.
 

chrism120

Aktives Mitglied
Also ich hatte mehrere Punkte angesprochen. Bitte konkret sagen, was Du genauer haben willst.

Der erste Punkt war eine Lösung, bei dem Du entweder einen oder keinen Datensatz zurück bekommst. Die Abfrage muss dann halt wie folgt aussehen:
SELECT HostName from Adresse where HostName = ?
Aufzubauen wäre dann die Abfrage selbst über ein PreparedStament ähnlich wie bei Deinem INSERT. (Zumindest gehe ich davon aus, dass Du das dort verwendet hast.)

Der zweite Punkt ist ein Fehler beim Auslesen des ResultSets. getString(2) gibt den Wert aus der zweiten Spalte. Aber Du hast nur eine Spalte (HostName).

Der dritte Punkt, ist der Logik-Fehler: Wenn Du in einer Schleife ein if/else hast, dann wird für jeden Wert in der Schleife entweder der if Part oder der else Part ausgeführt. Also wenn die ersten x Datensätze in das else laufen, dann hast Du das x mal ausgeführt ....

Ansonsten gefällt mir die Lösung von mihe7 sehr gut. Hier wäre aber noch die Frage, welche Datenbank Du genau verwendest. Einige haben dafür auch spezielle Lösungen (mysql/mariadb z.B.), die eben nicht Standard SQL sind.
Moin. ok Danke für deine Rückmeldung. ich verwende Mysql als Datenbank
 

chrism120

Aktives Mitglied
Hier mal ein Beispiel, mit MySQL getestet:
Java:
import java.sql.*;

public class Test {
    public static void main(String[] args) throws Exception {
        try(Connection conn = DriverManager.getConnection(args[0], args[1], args[2])) {
            createTable(conn);
            delete(conn, "127.0.0.1");
            insert(conn, "127.0.0.1", "localhost", Thread.currentThread().getId());
            insert(conn, "127.0.0.1", "localhost", Thread.currentThread().getId());       
        }
    }

    private static void createTable(Connection conn) {
        try(Statement stmt = conn.createStatement()) {
            stmt.execute("CREATE TABLE Adresse(ip varchar(20) not null primary key, " +
                         "HostName varchar(255) not null, " +
                         "ThreadNummer BIGINT not null);");        
        } catch (SQLException ex) {
            System.err.println("createTable: " + ex.getLocalizedMessage());
        }
    }

    private static void delete(Connection conn, String ip) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "DELETE FROM Adresse WHERE ip=?")) {
            stmt.setString(1, ip);
            int rowsDeleted = stmt.executeUpdate();
            System.out.printf("%d rows deleted.\n", rowsDeleted);
        }
    }

    private static void insert(Connection conn, String ip, String host, long thread) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "INSERT INTO Adresse(ip, HostName, ThreadNummer) " +
                "SELECT ?, ?, ? FROM (SELECT 1) x " +
                " WHERE NOT EXISTS (SELECT 1 FROM Adresse WHERE HostName = ?)")) {
            stmt.setString(1, ip);
            stmt.setString(2, host);
            stmt.setLong(3, thread);
            stmt.setString(4, host);

            int rowsInserted = stmt.executeUpdate();
            System.out.printf("%d rows inserted.\n", rowsInserted);
        }
    }

}

Bei einer Oracle DB müsstest Du "(SELECT 1) x" vermutlich durch "DUAL" ersetzen.

Auch die zweite Variante
Java:
    private static void insert(Connection conn, String ip, String host, long thread) throws Exception {
        try(PreparedStatement stmt = conn.prepareStatement(
                "INSERT INTO Adresse(ip, HostName, ThreadNummer) " +
                "SELECT ?, x.host, ? FROM (SELECT ? AS host) x " +
                " WHERE NOT EXISTS (SELECT 1 FROM Adresse WHERE HostName = x.host)")) {
            stmt.setString(1, ip);
            stmt.setLong(2, thread);
            stmt.setString(3, host);

            int rowsInserted = stmt.executeUpdate();
            System.out.printf("%d rows inserted.\n", rowsInserted);
        }
    }
funktioniert.
Morgen!! Danke.
 
K

kneitzel

Gast
Als erstes gefällt mit der Vorschlag von mihe7 sehr gut, denn der sollte so bei zumindest den meisten Datenbanken direkt funktionieren. Daher würde ich zu der Lösung raten!

Ich hatte aber MySQL spezifische Möglichkeiten angesprochen (Evtl. aufpassen, dass Du eine aktuelle mysql Version hast!):

INSERT IGNORE. Setzt ein unique key auf HostName voraus (So da jeder HostName nur einmal vorkommen soll, so sollte der auf jeden Fall gesetzt sein!) Dokumentation dazu wäre z.B.: http://www.mysqltutorial.org/mysql-insert-ignore/
Unter dem Strich ist es wie ein normales INSERT nur eben durch das IGNORE wird ein Fehler beim Uniqe Key nicht als Fehler behandelt sondern ignoriert. (Und die Datenbank dürfte da auch etwas optimieren hoffe ich...)

Interessant sind dann aber auch die Konstrukte (die Du aber hier nicht brauchst, da Du nur ein Insert machen willst und kein Update):
INSERT INTO ..... ON DUPLICATE KEY UPDATE .... ; http://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/
==> Dies ist ein zusammengefasstes INSERT und UPDATE statement. Da muss man dann nicht erst prüfen und dann entweder oder machen sondern hat einen kompakten Befehl.

REPLACE INTO ... http://www.mysqltutorial.org/mysql-replace.aspx
Dies ist prinzipiell ähnlich wie der INSERT ...ON DUPLICATE KEY ...

Ich selbst kenne diese Konstrukte, aber ich selbst vermeide diese so gut es geht, da es zusätzliche Abhängigkeiten schafft und eine Portierung erschwert.
 

chrism120

Aktives Mitglied
Als erstes gefällt mit der Vorschlag von mihe7 sehr gut, denn der sollte so bei zumindest den meisten Datenbanken direkt funktionieren. Daher würde ich zu der Lösung raten!

Ich hatte aber MySQL spezifische Möglichkeiten angesprochen (Evtl. aufpassen, dass Du eine aktuelle mysql Version hast!):

INSERT IGNORE. Setzt ein unique key auf HostName voraus (So da jeder HostName nur einmal vorkommen soll, so sollte der auf jeden Fall gesetzt sein!) Dokumentation dazu wäre z.B.: http://www.mysqltutorial.org/mysql-insert-ignore/
Unter dem Strich ist es wie ein normales INSERT nur eben durch das IGNORE wird ein Fehler beim Uniqe Key nicht als Fehler behandelt sondern ignoriert. (Und die Datenbank dürfte da auch etwas optimieren hoffe ich...)

Interessant sind dann aber auch die Konstrukte (die Du aber hier nicht brauchst, da Du nur ein Insert machen willst und kein Update):
INSERT INTO ..... ON DUPLICATE KEY UPDATE .... ; http://www.mysqltutorial.org/mysql-insert-or-update-on-duplicate-key-update/
==> Dies ist ein zusammengefasstes INSERT und UPDATE statement. Da muss man dann nicht erst prüfen und dann entweder oder machen sondern hat einen kompakten Befehl.

REPLACE INTO ... http://www.mysqltutorial.org/mysql-replace.aspx
Dies ist prinzipiell ähnlich wie der INSERT ...ON DUPLICATE KEY ...

Ich selbst kenne diese Konstrukte, aber ich selbst vermeide diese so gut es geht, da es zusätzliche Abhängigkeiten schafft und eine Portierung erschwert.
Danke
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ataria SQLite Werte aus zwei Tabellen zusammenführen Datenbankprogrammierung 8
Z Aus zwei bestehenden Table eine zusätzliche Gemeinsame machen (JavaFX) Datenbankprogrammierung 21
ralfb1105 Oracle Zwei ojdbc Driver in einer Applikation? Datenbankprogrammierung 13
W Problem mit Insert in zwei Tabellen Datenbankprogrammierung 8
O JDBC Daten in zwei Tabellen mit zwei foreach-Schleifen einfügen (insert into) Datenbankprogrammierung 1
M SQLite Zwei Datenbanken synchronisieren Datenbankprogrammierung 8
T MySQL MySQL - Insert into fügt zwei identische Datensätze ein Datenbankprogrammierung 2
AssELAss Oracle Wildcard-Suche über zwei Felder Datenbankprogrammierung 5
M Oracle XA Connect auf zwei Datenbankinstanzen | fertiges Tool verfügbar? Datenbankprogrammierung 0
K Zwei Datenbanken miteinander auf Unterschiede vergleichen Datenbankprogrammierung 2
C Entities zwischen zwei PersistenceUnits tauschen Datenbankprogrammierung 5
M MySQL größere von zwei Zahlen in Update Statement Datenbankprogrammierung 2
Consuelo Verbinden von zwei Tabellen, foreign key Datenbankprogrammierung 4
H SQL Abfrage - zwei tabellen vergleichen. Datenbankprogrammierung 2
D zwei gleichzeitige Connections Datenbankprogrammierung 2
C SQL String zwei Tabellen vergleichen und gleiche Zeile löschen Datenbankprogrammierung 25
J Mit einer Abfrage Worte suchen die in Zwei Tabellen enthalten sind Datenbankprogrammierung 5
N Zwei Spalten und Ihre Werte vergleichen Datenbankprogrammierung 3
P Insert into mit zwei Datenbanken Datenbankprogrammierung 3
G Inhalt eine Clob Feldes zw. zwei DB's kopieren Datenbankprogrammierung 2
W Zwei Fragen über JDBC und MySQL Datenbankprogrammierung 2
N Abfrage über zwei Datenbanken Datenbankprogrammierung 9
C Objekte aus DB in Strings umwandeln also von List<Objekt> in String Datenbankprogrammierung 6
J viele @Lob (Strings) mit JPA Datenbankprogrammierung 2
N [XLS]Strings in Excel-Tabelle schreiben (poi) Datenbankprogrammierung 2
H CREATE-Strings in Anwendung verwalten Datenbankprogrammierung 2
M Strings vergleichen Datenbankprogrammierung 8
X SQL Abfrage für Ähnlichkeit eines Strings Datenbankprogrammierung 2
T SUM für Strings Datenbankprogrammierung 2
N Fehler beim matchen von Strings via Query Datenbankprogrammierung 2
S SQL STRINGS Datenbankprogrammierung 9
L CSV Datei mit DB Inhalt vergleichen Datenbankprogrammierung 20
L MySQL Vergleichen von Array-Inhalt, Ausgabe gleicher Daten Datenbankprogrammierung 3
S MySQL Datenbankabfrage mit Eingabe aus Textfeld vergleichen Datenbankprogrammierung 4
MaxG. Datenbank werte vergleichen Datenbankprogrammierung 5
C Datenbankeinträge vergleichen Datenbankprogrammierung 16
V SQLite 2 Tabelle vergleichen und alle unterschiede rausgeben Datenbankprogrammierung 1
V SQLite 2 Tabellen vergleichen und nur Unterschiedliche Sätze rausgeben. Datenbankprogrammierung 31
Paul15 Tabelle vergleichen Datenbankprogrammierung 15
ruutaiokwu sql server 2008 stored procedures automatisiert vergleichen Datenbankprogrammierung 2
P Listen Vergleichen JPA Criteria Datenbankprogrammierung 2
T 2 Tabellen aus 2 Datenbanken miteinander vergleichen Datenbankprogrammierung 6
H Oracle Datumsformat vergleichen Datenbankprogrammierung 13
I DB-Zelleninhalt mit String vergleichen klappt nicht Datenbankprogrammierung 3
Gossi Oracle 2 Daten (Datum) vergleichen Datenbankprogrammierung 6
J Daten vergleichen Datenbankprogrammierung 10
S Daten einer Tabelle vergleichen und ggs neuen Wert einfügen Datenbankprogrammierung 8
E Vergleichen von datetime mit GregorianCalender-Werte Datenbankprogrammierung 6

Ähnliche Java Themen

Neue Themen


Oben