# Pürfen ob ID bereits vorhanden



## Lia (3. Jul 2018)

Hi ihr lieben,

Ich habe eine Frage, und zwar habe ich ein Panel indem drei Textfelder sind. Eins ist für den Vorname, das andere für den Nachnamen und das dritte für die ID.

Damit soll der Benutzer sich anmelden. Diese drei Informationen werden in der Datenbank hinterlegt, dass funktioniert soweit. 

Nun möchte ich, FALLS diese ID (zb. 1244(irgendeine Nummer), bereits in der DB existiert eine MsgBox ausgeben ("Willkommen zurück"). (Wenn ich zur Zeit die gleiche Nummer die bereits in der DB existiert eingebe, kommt eine Fehlermeldung mit (duplikat), mir ist auch klar warum(Primary key). Das möchte ich verhindern ich möchte das er quasi trotzdem ins nächste Menüfenster kommt.  

Falls die ID neu ist und noch nicht in der Datenbank vorhanden ist, soll einfach eine Meldung mit ("Willkommen bei..") erscheinen. (Das sollte ich hinbekommen). Aber das obere Problem bekomme ich nicht gelöst.

Vielen Dank an jede Antwort.


----------



## httpdigest (3. Jul 2018)

Du könntest z.B. eine count query machen:

```
try (PreparedStatement stmt = connection.prepareStatement(
       "SELECT count(id) FROM my_table WHERE id = ?")) {
  stmt.setInt(1, theId); // <- theId ist die gesuchte ID
  try (ResultSet rs = stmt.executeQuery()) {
    rs.next(); // <- es gibt im Erfolgsfall IMMER eine Ergebniszeile
    return rs.getInt(1) == 1;
  }
}
```


----------



## Lia (3. Jul 2018)

@httpdigest , ich hoffe ich konnte ungefähr erklären was mein Problem ist . Wenn die ID vorhanden ist, trotzdem ins nächste Panel wechseln und nichts in die DB einfügen. Ich habe das mal versucht umzusetzen was du mir geschickt hast, aber irgendwie bin ich total verwirrt 

if (bla….){}
      else if(r1.next()) {
       pst2.setString(1, txtgetID.getText());
       r1.next();
       return r1.getString(1)==1;​
Das Problem ist auch, das ich mit setString mein textField setze (obwohl es ein Integer ist) aber beim getString funktioniert das natürlich nicht. Ich hoffe du kannst mir weiter helfen. DANKE


----------



## httpdigest (3. Jul 2018)

Ich habe das Problem schon verstanden, und mit der Query, die ich geschrieben habe, kannst du herausfinden, ob die ID bereits in der Tabelle existiert oder nicht. Wenn du einen String hast, dann wandele ihn einfach in ein int um mit Integer.valueOf(string).

EDIT: Vielleicht hilft es dir besser, wenn wir den Codeschnipsel zum Abfragen der Existenz der ID explizit in eine Methode verpacken (so war es auch gedacht):

```
public static boolean existiertId(Connection connection, int theId) throws SQLException {
  try (PreparedStatement stmt = connection.prepareStatement(
         "SELECT count(id) FROM my_table WHERE id = ?")) {
    stmt.setInt(1, theId); // <- theId ist die gesuchte ID
    try (ResultSet rs = stmt.executeQuery()) {
      rs.next(); // <- es gibt im Erfolgsfall IMMER eine Ergebniszeile
      return rs.getInt(1) == 1;
    }
  }
}
```


----------



## Lia (3. Jul 2018)

@httpdigest , kann ich das hier direkt machen return r1.getString(1)==1;
ich hab sie nämlich sonst in keiner zwischenvariable oder so


----------



## httpdigest (3. Jul 2018)

Wieso denn `getString(1)`? Wenn r1 bei dir das ResultSet ist, welches das Ergebnis der count-Query enthält, dann willst du doch aus der Query keinen String zurückbekommen... Der count ist immer eine Zahl, die du z.B. mit getInt(1) holen kannst.


----------



## Lia (3. Jul 2018)

ich bekomme ne Fehlermeldung , das alles befindet sich ja in einem ButtonClick und dieser liefert nur void und wenn ich da ein return int stehen habe, bekomme ich einen Fehler..


----------



## httpdigest (3. Jul 2018)

Schau dir nochmal den Code hier an: https://www.java-forum.org/thema/puerfen-ob-id-bereits-vorhanden.182031/#post-1157802


----------



## Lia (4. Jul 2018)

@httpdigest sorry ich dreh gleich durch , schau mal habe das hier ausprobiert, aber wenn ich das ausführe bekomme ich die Meldung "No value specified for parameter 1"


```
String query1 = "SELECT COUNT(ID) FROM Student WHERE ID= ?";
     PreparedStatement pst1 = con.prepareStatement(query1);
     ResultSet r1= pst1.executeQuery();
       pst1.setString(1, txtFieldID.getText());
       int n = 0;
       if ( r1.next() ) {
           n = r1.getInt(1);
       if ( n > 0 ) {
        JOptionPane.showMessageDialog(null,"user existiert");
       }
     // }
      }
```

ICH MUSS DAZU SAGEN: DAS DIE ID IN MEINER TABELLE AN POSITION NR 3 STEHT, ich denke es hat auch was damit zu tun


----------



## mrBrown (4. Jul 2018)

Die Fehlermeldung ist doch eindeutig 

Guck mal, wann du die Query ausführst, und wann du den Parameter setzt 



Lia hat gesagt.:


> ICH MUSS DAZU SAGEN: DAS DIE ID IN MEINER TABELLE AN POSITION NR 3 STEHT, ich denke es hat auch was damit zu tun


Nein.


----------



## httpdigest (4. Jul 2018)

Desweiteren: Hat die Spalte "ID" in der Datenbank einen String-Typ (VARCHAR, VARCHAR(N), CHAR(N), TEXT, ...) oder einen integralen Typ (INTEGER, NUMBER, NUMERIC, BIGINT, ...)?
Dementsprechend musst du den Parameter auch entweder per setString() oder setInt() setzen. Meine Vermutung war, dass ID einen integralen Typ hat, also setInt() verwendet werden muss.


----------



## Lia (4. Jul 2018)

@mrBrown & @httpdigest danke !!!!!!


```
int n= 0;
     if ( r1.next() ) {
         n = r1.getInt(1);
      if ( n > 0 ) {
       JOptionPane.showMessageDialog(null,"Willkommen zurück");
       CardLayout card = (CardLayout)pnlGesamt.getLayout();
       card.show(pnlGesamt, "panel_8");
      }
      else {
       pst1.close();
      }
     }
```

So funktioniert es soweit, das Problem ist nur das er mir eine Exception schmeißt mit Duplicate entry '11' for key 'PRIMARY' ich weiß ja das diese ID vorhanden ist, genau das möchte ich ja, dass wenn die ID vorhanden ist ein "Willkommen zurück" ohne diese Exception


----------



## httpdigest (4. Jul 2018)

Ich frage nochmal: Hat die Spalte "ID" in der Datenbank einen String-Typ (VARCHAR, VARCHAR(N), CHAR(N), TEXT, ...) oder einen integralen Typ (INTEGER, NUMBER, NUMERIC, BIGINT, ...)?
Dementsprechend musst du den Parameter auch entweder per setString() oder setInt() setzen. Meine Vermutung war, dass ID einen integralen Typ hat, also setInt() verwendet werden muss.


----------



## Lia (4. Jul 2018)

INTEGER NOT NULL PRIMARY KEY ja genau integraler typ
aber dadurch das ich ein Textfield habe txtFieldID.getText() habe ich es als getString


----------



## httpdigest (4. Jul 2018)

httpdigest hat gesagt.:


> Ich habe das Problem schon verstanden, und mit der Query, die ich geschrieben habe, kannst du herausfinden, ob die ID bereits in der Tabelle existiert oder nicht. *Wenn du einen String hast, dann wandele ihn einfach in ein int um mit Integer.valueOf(string).*


Und verwende (wie schon zigmal gesagt) setInt(1, theId) im PreparedStatement.


----------



## Lia (4. Jul 2018)

Ok das funktioniert  danke , aber die Exception mit dem Duplikat, die kann ich nicht irgendwie umgehen oder? Also das einfach nur weiter mache, wenn die ID vorhanden ist


----------



## mrBrown (4. Jul 2018)

Lia hat gesagt.:


> So funktioniert es soweit, das Problem ist nur das er mir eine Exception schmeißt mit Duplicate entry '11' for key 'PRIMARY' ich weiß ja das diese ID vorhanden ist, genau das möchte ich ja, dass wenn die ID vorhanden ist ein "Willkommen zurück" ohne diese Exception


Du darfst halt nichts hinzufügen, wenn dir das zurückgibt, dass es den Eintrag schon gibt?

Zeig doch mal die entsprechenden Zeilen


----------



## Lia (4. Jul 2018)

```
String query = "INSERT INTO User(Name,Adress,ID) VALUES(?,?,?)";
     String query1 = "SELECT COUNT(ID) FROM User WHERE ID= ?";
  
    
     PreparedStatement pst1 = con.prepareStatement(query1);
     pst1.setInt(1, Integer.valueOf(txtFieldID.getText()));
     ResultSet r1= pst1.executeQuery();
    
     int n= 0;
     if ( r1.next() ) {
         n = r1.getInt(1);
      if ( n > 0 ) {
       JOptionPane.showMessageDialog(null,"Willkommen zurück");
       CardLayout card = (CardLayout)panelUser.getLayout();
       card.show(panelUser, "panel_2");
      }
      else {
       pst1.close();
      }
     }

     PreparedStatement pst = con.prepareStatement(query);
     pst.setString(1, txtFieldName.getText());
     pst.setString(2, txtFieldAdress.getText());
     pst.setString(3, txtFieldiD.getText());
else {
 
      pst.execute();
      pst.close();
      JOptionPane.showMessageDialog(null, "Eintrag wurde erfolgreich hinzugefügt");
```

Das ist alles @mrBrown. Falls vorhanden, dann willkommen zurück ohne es als Duplikat einzufügen oder sonstiges und falls neu dann die Meldung Eintrag wurde erfolgreich hinzugefügt


----------



## mihe7 (4. Jul 2018)

@Lia benutz doch bitte die CODE-Tags, das ist ja fürchterlich.

Ansonsten führst Du das Einfügen aus, egal, ob n > 0 ist oder nicht. Im Klartext: nach dem card.show fehlt ein return.

Allerdings wäre es wesentlich besser, Du würdest den Code einfach mal halbwegs vernünftig strukturieren (@httpdigest hat Dir Anfangs schon eine separate Methode geschrieben), dann passieren solche Dinge nicht so leicht.

Was Du willst:

```
wenn der Benutzer mit gegebener ID bereits existiert dann
   willkommen zurück
sonst
   füge benutzer hinzu
```

Das lässt sich 1:1 in Code gießen:


```
if (userExists(id)) {
    welcomeBack();
} else {
    addUser(...);
}
```

Jetzt schreibst Du noch die drei Methoden und das Thema ist erledigt.


----------

