# ODBC-Befehle gesucht



## Reality (20. Mrz 2004)

Hi!
Ich habe ein großes Problem! Meine Mutter hat meine Unterlagen zur ODBC-Programmierung weggeschmissen, die ich von meinem Lehrer bekommen habe. Die ANleitung dort war perfekt und einfach.
Im Internet wurde ich nur teilweise fündig. Eine Connection habe ich jedenfalls schon hingekriegt. Wenn ich aber etwas eintragen will, wird die Exception ausgelöst!
Kann mir jemand erklären, was da falsch ist?

```
void btEintragen_actionPerformed(ActionEvent e) {
  try{
String fremdwort=tfFremdwort.getText();
String uebersetzung=tfUebersetzung.getText();
String eintrag="INSERT INTO tabelle1 (Fremdwort, Uebersetzung) VALUES ('"+fremdwort+"',"+"'uebersetzung')";

Statement stmt = con.createStatement();
ResultSet rst = stmt.executeQuery(eintrag);
lbEintrag.setText("Eintrag war erfolgreich!");


}catch(Exception fx){
System.out.println("Fehler beim Eintragen der Daten!");
}
  }
```

Dann würde ich auch gerne wissen, wie ich das Ergebnis wieder ausgebe.

Liebe Grüße
Reality


----------



## Guest (20. Mrz 2004)

Es wäre einfacher, wenn Du die Exception angeben würdest, ggf. mit Stacktrace. Die Exception und den StackTrace kannst Du ausgeben mit

```
ex.printStackTrace(); // wobei ex deine Exception ist
```


----------



## Reality (20. Mrz 2004)

Hi, 
folgendes kam:

```
java.sql.SQLException: No ResultSet was produced

	at sun.jdbc.odbc.JdbcOdbcStatement.executeQuery(JdbcOdbcStatement.java:235)

	at HauptFenster.btEintragen_actionPerformed(HauptFenster.java:129)

	at HauptFenster$4.actionPerformed(HauptFenster.java:66)

	at java.awt.Button.processActionEvent(Button.java:329)

	at java.awt.Button.processEvent(Button.java:302)

	at java.awt.Component.dispatchEventImpl(Component.java:2595)

	at java.awt.Component.dispatchEvent(Component.java:2499)

	at java.awt.EventQueue.dispatchEvent(EventQueue.java:336)

	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:134)

	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:101)

	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:96)

	at java.awt.EventDispatchThread.run(EventDispatchThread.java:88)
```

Ich glaube, dass der Befehl nicht mit ResulSet ausgeführt werden darf.

Liebe Grüße
Reality


----------



## Guest (20. Mrz 2004)

Du führst keinen Query durch sondern einen Insert. Bei dem wird kein ResultSet erzeugt sondern ggf. nur die Anzahl der Zeilen zurückgegeben, die von dem Insert betroffen waren. Also kein ResultSet.

Schau mal in die Docs von java.sql.Statement und verwendet anstatt executeQuery(...)  die Methode executeUpdate(...)


----------



## Reality (20. Mrz 2004)

Hi,
da kommt folgende Fehlermeldung:

```
"HauptFenster.java": Fehler #: 354 : Inkompatible Typen; int wurde gefunden, java.sql.ResultSet ist erforderlich in Zeile 129, Spalte 35
```

Liebe Grüße
Reality


----------



## Guest (20. Mrz 2004)

Hast Du noch folgendes Statement stehen? 

```
ResultSet rst = stmt.executeUpdate(eintrag);
```

executeUpdate liefert int, daher muss es heissen

```
int result = stmt.executeUpdate(eintrag);
```

welche IDE benutzt Du?


----------



## Reality (20. Mrz 2004)

Hi!
Ich danke dir für deine Hilfe! 
Lässt sich das auch irgendwie logisch erklären, warum das jetzt int sein muss?
Ich benutze Borland JBuilder 5 Personal Edition.

Liebe Grüße
Reality


----------



## Guest (20. Mrz 2004)

int weil die Zahl der Zeilen zurückgegeben wird, die von Deinem Insert betroffen waren. Normalerweise 1. Aber Du kannst daran erkennen, ob überhaupt was auf der Datenbank passiert ist. 

Ich hab die Frage wegen der IDE gestellt, weil ich eclipse benutze und einige Deiner Fehler eclipse bereits beim eintippen anzeigt und man die daher schnell beseitigen kann.


----------



## Reality (20. Mrz 2004)

Hi,
ich habe ein neues Problem.
Ich weiss nicht genau, wie ich nun die Wörter in der DB anzeigen soll. Ich weiß nur, wie ich Das erste Wort der ersten Tabelle anzeigen lassen kann:


```
void btAnzeigen_actionPerformed(ActionEvent e) {
  try{
  String anzeigen="SELECT * FROM tabelle1";

  Statement stmt=con.createStatement();
  ResultSet rst = stmt.executeQuery(anzeigen);

  boolean more=rst.next();
  while(more) {
    listAnzeigen.setText(rst.getString("Fremdwort")+"\n");
    more=rst.next();
    }
  }catch(SQLException d){
  d.printStackTrace();
  }
  }
```

Ich habe 2 Tabellen: Fremdwort; Uebersetzung. Und ich will, dass beides angezeigt wird.

Liebe Grüße
Reality


----------



## Guest (20. Mrz 2004)

Hast Du tatsächlich zwei Tabellen oder hast Du in einer Tabelle zwei Spalten? Beim Insert oben hast Du eine Tabelle mit zwei Spalten gehabt.

Falls Du nur eine Tabelle hast, kannst Du auf die Spalten der Tabelle zugreifen, indem Du zuerst die Spalten in der Select-Anweisung auswählst oder "select *" benutzt und dann im ResultSet die Spalten bei Spaltennamen oder per SpaltenIndex ansprichst. Ich würd aber immer wenn möglich den Spaltennamen nehmen, denn ansonsten müsst Du ggf. Deine Zugriffsmethoden ändern, wenn Du im Datenbankschema eine Spalte hinzufügst.

Zugriff also:


```
try{
  String anzeigen="SELECT * FROM tabelle1";

  Statement stmt=con.createStatement();
  ResultSet rst = stmt.executeQuery(anzeigen);

  while(rst.next()) {
    String fremdword = rst.getString("Fremdwort");
    String uebersetzung = rst.getString("Uebersetzung");

    listAnzeigen.setText( ... ); // fremdword und uebersetzung zusammensetzen
    }
  }catch(SQLException d){
  d.printStackTrace();
  }
```

nachher im finally nicht vergessen, das ResultSet und die Connection zu schliessen.

das mit dem while(more) ist übrigens ziemlich gefährlich. Wenn Du vergisst den boolean more entsprechend zu setzen, hast Du eine Einlosschleife.

Wenn Du nun doch zwei Tabellen hast, dann poste mal das Datenbankschema, damit wir sehen können, wie die Tabellen verknüpft sind.


----------



## Reality (20. Mrz 2004)

Hi! 
Ja, sorry, meinte 2 Spalten.
1 Schritt weiter bin ich jetzt schon mal, jedoch zeigt es nur den letzten Eintrag an. Woran liegt das?

Liebe Grüße
Reality


----------



## Nook (20. Mrz 2004)

Hab mich mal angemeldet ... 

Du siehst nur die letzte Spalte, weil du zwar mit der While-Schleife durch den ganzen ResultSet gehst, aber das Ergebnis des vorherigen Durchlaufes in listAnzeigen.setText(..) immer überschreibst. Ich nehm mal an, listAnzeigen ist ein TextArea oder sowas?!

Du kannst die Ergebnisse des ResultSets vielleicht besser in einem StringBuffer sammeln:


```
StringBuffer buf = new StringBuffer();
while(...) {
...
buf.append(fremdword).append(" = ").append(uebersetzung).append("\n");
}

listAnzeigen.setText(buf.toString());
```


----------



## Reality (20. Mrz 2004)

Hi Nook!
Endlich mal ein Name. 
Du bist wirklich ein Meister in Fehlererkennung! Ja, es ist eine Textarea. Wenn ich jedoch den Quelltext so hinschreibe, beschwert es sich, dass es die variablen uebersetzung und fremdwort nicht gibt. Ist wohl so, wenn man variablen in whileschleifen deklariert und initialisiert.

Gibt es stattdessen etwas besser als Textarea?

Liebe Grüße
Reality


----------



## Nook (20. Mrz 2004)

das buf.append(..) sollte schon in der Whileschleife erfolgen. Ansonsten sind ja die Variablen fremdword und uebersetzung nicht vorhanden.

Mit StringBuffer generiest Du im Grunde resourcenarm einen String. Man könnte das genauso mit einem String machen und jeweils mit "+" etwas an den String dranhängen. Bei wenigen "+" Operationen ist das mit dem String noch Ok, aber wenn Du schon eine Datenbanktabelle ausliest, ist StringBuffer immer vorzuziehen. 

TextArea bzw. JTextArea hat erstmal nichts damit zu tun, wie Du die Daten von der Datenbank liest und zur Darstellung aufbereitest.  Bei der späteren Darstellung des mehrzeiligen Ergebnisses ist (J)TextArea genau richtig. Setze es dafür dann auf setEditable(false), da Du ja vermutlich das Ergebnis nicht über die TextArea veränderbar machen möchtest.


----------



## Reality (20. Mrz 2004)

Hi,
hier kannst du dich überzeugen:


```
void btAnzeigen_actionPerformed(ActionEvent e) {
  try{
  String anzeigen="SELECT * FROM tabelle1";
  StringBuffer buf = new StringBuffer();

  Statement stmt=con.createStatement();
  ResultSet rst = stmt.executeQuery(anzeigen);

    while(rst.next()) {
    String fremdwort = rst.getString("Fremdwort");
    String uebersetzung = rst.getString("Uebersetzung");
    buf.append(fremdwort).append(" = ").append(uebersetzung).append("\n");
    
    }
    listAnzeigen.setText(fremdwort+" = "+uebersetzung);
  }catch(SQLException d){
  d.printStackTrace();
  }
  }
```


```
"HauptFenster.java": Fehler #: 300 : Variable fremdwort nicht gefunden in Klasse HauptFenster in Zeile 188, Spalte 26
"HauptFenster.java": Fehler #: 300 : Variable uebersetzung nicht gefunden in Klasse HauptFenster in Zeile 188, Spalte 42
```

Liebe Grüße
Reality


----------



## Nook (20. Mrz 2004)

Reality hat gesagt.:
			
		

> Hi,
> hier kannst du dich überzeugen:
> 
> 
> ...


----------



## Reality (20. Mrz 2004)

Oh!  
Noch eine Frage 
WIe kann ich die ganzen Ergebnisse in einem Balken darstellen lassen? Also dass man dann runterscrollen kann.

Liebe Grüße
Reality


----------



## Nook (20. Mrz 2004)

Um JTextArea scrollbar zu machen, stecke es in ein JScrollPane.

Ausschnitt von Swing-Tutorial
(den Source findest Du, wenn Du dem Link "exampleIndex" folgst)

```
...
 JTextArea textArea = new JTextArea(
                "This is an editable JTextArea. " +
                "A text area is a \"plain\" text component, " +
                "which means that although it can display text " +
                "in any font, all of the text is in the same font."
        );
        textArea.setFont(new Font("Serif", Font.ITALIC, 16));
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        JScrollPane areaScrollPane = new JScrollPane(textArea);
        areaScrollPane.setVerticalScrollBarPolicy(
                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
...
[code]
```


----------



## Reality (20. Mrz 2004)

Danke, vielmals! 
Habe es über den Design-Modus von JBuilder gemacht, ist einfacher. 

Liebe Grüße
Reality


----------



## Reality (21. Mrz 2004)

Hi,
folgender UPDATE-Befehl geht nicht!


```
void btBearbeiten_actionPerformed(ActionEvent e) {
String wort1= tfWort1.getText();
String wort2=tfWort2.getText();

String update="UPDATE tabelle1 SET "+wort1+" = "+wort2;
try
    {
Statement stmt=con.createStatement();
int updaten=stmt.executeUpdate(update);
lbUpdate.setText("Update war erfolgreich!");
    }catch (SQLException fx)
      {
    fx.printStackTrace();
      }
  }
```

Folgende Exception wird ausgelöst:

```
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] 2 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben.
	at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6031)
	at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:6188)
	at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java:2494)
	at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcStatement.java:314)
	at sun.jdbc.odbc.JdbcOdbcStatement.executeUpdate(JdbcOdbcStatement.java:264)
	at HauptFenster.btBearbeiten_actionPerformed(HauptFenster.java:236)
	at HauptFenster$7.actionPerformed(HauptFenster.java:113)
	at java.awt.Button.processActionEvent(Button.java:329)
	at java.awt.Button.processEvent(Button.java:302)
	at java.awt.Component.dispatchEventImpl(Component.java:2595)
	at java.awt.Component.dispatchEvent(Component.java:2499)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:336)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:134)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:96)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:88)
```

Woran kann das liegen?!

Liebe Grüße
Reality


----------



## Nook (21. Mrz 2004)

Der SQL-Updatebefehl sind folgendermassen aus:

```
UPDATE table_name SET column_name = new_value WHERE column_name = some_value
```



D.h. Du muss einen Spaltennamen angeben dessen Wert verändert wird. Damit nicht mehrere Werte in dieser Spalte verändert werden, gibtst Du eine Where-Bedingung mit, in der Du den alten Spaltenwert angibst, sodass die entsprechende Zeile innerhalb der Tabelle gefunden werden kann.

Normalerweise hat eine Tabelle eine Spalte, die das Schlüsselattribut verwendet. Dieser Schlüssel für einen Datensatz (die Werte einer Zeile) ist innerhalb der Tabelle eindeutig. Der Schlüssel kann z.B. eine Zahl sein. Ggf. wird diese Zahl von der Datenbank selber vergeben. Wenn Du z.B. das Schlüsselattribut auf AUTO-INCREMENT setzt, wird bei jedem Einfügen eines neuen Datensatzes automatisch das Schlüsselattribut um einen Wert erhöht.

Falls Du keinen Schlüssel hast, funktioniert der Update erstmal auch, es kann Dir aber passieren, dass mehrere Zeilen verändert werden.

Insgesamt muss Du also den Update-Befehl verändern:

```
String update="UPDATE tabelle1 SET Uebersetzung = "+wort1+" where Fremdwort="+word2;
```

vorrausgesetzt Du willst die Übersetzung für ein Fremdwort ändern.


----------



## Reality (21. Mrz 2004)

Hi,


> vorrausgesetzt Du willst die Übersetzung für ein Fremdwort ändern.


ich habe mir das so vorgestellt:
Z.B. habe ich das Fremdwort archaisch falsch geschrieben und will es deswegen bearbeiten. So soll er mit das Wort finden und es so umändern, wie es der Benutzer angegeben hat. Genauso soll es bei Uebersetzung passieren.

wort 1 stellt dabei das Orignalwort dar, dass verändert wird und wort2 ist die Modifikation.

Liebe Grüße
Reality


----------



## Nook (21. Mrz 2004)

```
String update="UPDATE tabelle1 SET Fremdwort = "+wort2+" where Fremdwort="+word1;
```

bei Übersetzung entsprechend. 

Ich würde aber eher einen Tabellenschlüssel verwenden (s.o). Das Prozedere ist dann wie folgt:

User will ein Wort ändern:
1) Du liest den entsprechenden Datensatz aus der Tabelle aus. Hast nun neben (Fremdwort, Uebersetzung) die ID, also den Tabellenschlüssel  des Datensatzes.
2) User ändert das Wort
3) update der Tabelle wobei in der Where-Bedingung mit der ID nach dem zu ändernden Datensatz gesucht wird.


----------



## Reality (21. Mrz 2004)

Hi,


> User will ein Wort ändern:
> 1) Du liest den entsprechenden Datensatz aus der Tabelle aus. Hast nun neben (Fremdwort, Uebersetzung) die ID, also den Tabellenschlüssel  des Datensatzes.
> 2) User ändert das Wort
> 3) update der Tabelle wobei in der Where-Bedingung mit der ID nach dem zu ändernden Datensatz gesucht wird.


danke, für den Tipp, will ich aber erst später machen.

Leider geht das immer noch nicht.
Diese Fehlermeldung kommt:

```
java.sql.SQLException: [Microsoft][ODBC Microsoft Access Driver] 2 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben.
	at sun.jdbc.odbc.JdbcOdbc.createSQLException(JdbcOdbc.java:6031)
	at sun.jdbc.odbc.JdbcOdbc.standardError(JdbcOdbc.java:6188)
	at sun.jdbc.odbc.JdbcOdbc.SQLExecDirect(JdbcOdbc.java:2494)
	at sun.jdbc.odbc.JdbcOdbcStatement.execute(JdbcOdbcStatement.java:314)
	at sun.jdbc.odbc.JdbcOdbcStatement.executeUpdate(JdbcOdbcStatement.java:264)
	at HauptFenster.btBearbeiten_actionPerformed(HauptFenster.java:238)
	at HauptFenster$7.actionPerformed(HauptFenster.java:113)
	at java.awt.Button.processActionEvent(Button.java:329)
	at java.awt.Button.processEvent(Button.java:302)
	at java.awt.Component.dispatchEventImpl(Component.java:2595)
	at java.awt.Component.dispatchEvent(Component.java:2499)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:336)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:134)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:96)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:88)
```


```
void btBearbeiten_actionPerformed(ActionEvent e) {
String wort1= tfWort1.getText();
String wort2=tfWort2.getText();

String update;
update="UPDATE tabelle1 SET Fremdwort = "+wort2+" where Fremdwort= "+wort1;
try
    {
Statement stmt=con.createStatement();
int updaten=stmt.executeUpdate(update);
lbUpdate.setText("Update war erfolgreich!");
    }catch (SQLException fx)
      {
    fx.printStackTrace();
      }
  }
```

Ein Kumpel von mir hat ebenfalls kein Update mit JAVA hingekriegt. Er meinte, dass das mit Java nicht gehen würde. Mit VB kriegt er es jedenfalls hin.

Liebe Grüße
Reality[/quote]


----------



## Nook (21. Mrz 2004)

seh ich grad erst, quotiere mal die Variablen im String


```
update="UPDATE tabelle1 SET Fremdwort =\ ""+wort2+"\" where Fremdwort="\ "+wort1+"\"";
```

Mit welchen Worten testest Du denn den Update?


----------



## Reality (21. Mrz 2004)

Hi, 
danke! Hab zwar den Code etwas umgeändert, weil er mir zu unübersichtlich war und du ein paar Fehler eingebaut hast, aber jetzt geht´s! 

```
update="UPDATE tabelle1 SET Fremdwort = '"+wort2+"' where Fremdwort= '"+wort1+"'";
```

Liebe Grüße
Reality


----------



## Nook (21. Mrz 2004)

wie fehler eingebaut ?


----------



## Reality (22. Mrz 2004)

Z.B.
da:

```
=\ ""+wort2+
```
SOllte heissen

```
=\""+wort2+
```


----------



## Nook (22. Mrz 2004)

klar, so hatte ich das auch eingetippt, dann ist das wohl beim posten schief gegangen.


----------

