Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Datenbanken aktualisieren
executeUpdate() <ul><li>Die Methode  executeUpdate()  wird eingesetzt für: </li></ul><ul><ul><li>INSERT ,  UPDATE  und  DE...
Beispiel für executeUpdate() <ul><li>Anlegen einer Tabelle: </li></ul><ul><li>stmt.executeUpdate( </li></ul><ul><li>  &quo...
execute()
execute() <ul><li>Die Methode  stmt.execute()  ist die Verallgemeinerung von  stmt.executeQuery()  und  stmt.executeUpdate...
getResultSet(), getUpdateCount()  <ul><li>Liefert  execute()  den Rückgabewert  true , dann gibt es ein  ResultSet , welch...
getUpdateCount() <ul><li>getUpdateCount()  ergibt die Anzahl geänderten Tupel zurück. </li></ul><ul><ul><li>> 0 Es war ein...
execute() und mehrere ResultSets <ul><li>Mit  execute()  kann es vorkommen, dass mehrere  ResultSet s zurückkommen, etwa b...
Aktualisierbare ResultSets
Veränderbare ResultSets <ul><li>Im Allgemeinen muss man für die Manipulation der Datensätze UPDATE-SQL-Anweisungen abschic...
Kann man das ResultSet updaten? <ul><li>Bekommt man als Parameter ein  ResultSet , und möchte wissen, ob man es updaten ka...
Aktualisieren <ul><li>Zum Aktualisieren der Zeilen bietet das  ResultSet  die  updateXXX() -Methoden. </li></ul><ul><ul><l...
Die erste Zeile verändern <ul><li>Statment stmt = con.createStatement( </li></ul><ul><li>  ResultSet.TYPE_SCROLL_SENSITIVE...
Zeilen einfügen <ul><li>Um Zeilen einzufügen, erzeugt man mit  moveToInsertRow()  eine neue Zeile, die man dann mit den be...
Zeilen löschen <ul><li>deleteRow()   löscht die aktuelle Zeile. </li></ul><ul><li>Um eine bestimmte Zeile zu löschen, kann...
CONCUR_UPDATABLE, (IN)SENSITIVE  <ul><li>Immer dann, wenn  CONCUR_UPDATABLE  gesetzt ist, bekommt man einen Cursor, der Än...
Zeile neu beziehen <ul><li>Im Fall, dass während einer längeren Abfrage sich Daten im Hintergrund ändern können, bezieht  ...
Batch-Verarbeitung
addBatch() <ul><li>Seit JDBC 2.0 können mehrere SQL-Anweisungen als Bündel an die Datenbank geschickt werden. </li></ul><u...
Batch-Beispiel mit Statement <ul><li>Connection con = ...; </li></ul><ul><li>conn.setAutoCommit( false ); </li></ul><ul><l...
Beispiel mit PreparedStatement <ul><li>con.setAutoCommit( false ); </li></ul><ul><li>String ps = &quot;INSERT INTO Tabelle...
Veränderte Zeilen <ul><li>Die Funktion  executeBatch()  liefert ein Feld von Ganzzahlen, die die Anzahl veränderten Zeilen...
Fehlerbehandlung <ul><li>Falls im Batch-Prozess etwas schief läuft, gibt es eine  BatchUpdateException . </li></ul><ul><li...
Veränderte Zeilen bei Exception <ul><li>Wird  executeBatch()  aufgerufen und eine  BatchUpdateException   folgt, kann man ...
getUpdateCounts() <ul><li>Die Funktion  e.getUpdateCounts()  liefert im Feld noch andere Informationen:  </li></ul><ul><li...
Professionelle IT-Qualifizierung
tutego über tutego <ul><li>Inhouse-Schulungen mit individualisierten Inhalten und Terminauswahl </li></ul><ul><li>190 Semi...
Unsere Themen
Unsere Themen
Nächste SlideShare
Wird geladen in …5
×

SQL-Updates mit der JDBC-API

2.283 Aufrufe

Veröffentlicht am

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

SQL-Updates mit der JDBC-API

  1. 1. Datenbanken aktualisieren
  2. 2. executeUpdate() <ul><li>Die Methode executeUpdate() wird eingesetzt für: </li></ul><ul><ul><li>INSERT , UPDATE und DELETE -Operationen. </li></ul></ul><ul><ul><li>DDL Anweisungen wie CREATE TABLE , DROP TABLE , ALTER . </li></ul></ul><ul><li>Änderungen werden ausgeführt mit </li></ul><ul><li>int count = stmt.executeUpdate ( sql ); </li></ul><ul><li>executeUpdate() besitzt den Rückgabetyp ist, der bei </li></ul><ul><ul><li>INSERT , UPDATE und DELETE die Anzahl der veränderten Tupel zurückliefert (Update-Count), </li></ul></ul><ul><ul><li>sonst 0. </li></ul></ul>
  3. 3. Beispiel für executeUpdate() <ul><li>Anlegen einer Tabelle: </li></ul><ul><li>stmt.executeUpdate( </li></ul><ul><li> &quot;CREATE TABLE Personen (&quot; + </li></ul><ul><li> &quot;Name VARCHAR(25) NOT NULL, &quot; + </li></ul><ul><li> &quot;Alter INTEGER NOT NULL) &quot; ); </li></ul><ul><li>Einfügen einer Zeile </li></ul><ul><li>stmt.executeUpdate(&quot;INSERT INTO Personen&quot; + </li></ul><ul><li> &quot; (Name, Alter) &quot; + </li></ul><ul><li> &quot;VALUES ('Ullenboom', 102)&quot; ); </li></ul><ul><li>Löschen der Tabelle </li></ul><ul><li>stmt.executeUpdate( &quot;DROP TABLE Personen&quot; ); </li></ul>
  4. 4. execute()
  5. 5. execute() <ul><li>Die Methode stmt.execute() ist die Verallgemeinerung von stmt.executeQuery() und stmt.executeUpdate() . </li></ul><ul><li>Die Funktion ist immer dann nützlich, wenn unbekannte SQL-Anweisungen ausgeführt werden. </li></ul><ul><li>Dennoch verrät execute() über die Rückgabe den Typ: </li></ul><ul><ul><li>true : das Ergebnis ist ein ResultSet </li></ul></ul><ul><ul><li>false : ein Update-Count oder kein Ergebnis. </li></ul></ul><ul><li>Auch wird execute() für SQL-Anweisungen verwendet, die mehr als einen Rückgabewert oder Update-Count liefern. </li></ul>
  6. 6. getResultSet(), getUpdateCount() <ul><li>Liefert execute() den Rückgabewert true , dann gibt es ein ResultSet , welches man mit getResultSet() erfragen kann. </li></ul><ul><li>Statement stmt = conn.createStatement(); </li></ul><ul><li>boolean isQuery = stmt.execute ( &quot;SELECT …&quot; ); </li></ul><ul><li>if ( isQuery ) { </li></ul><ul><li> ResultSet rs = stmt.getResultSet() ; </li></ul><ul><li> ... </li></ul><ul><li>} </li></ul><ul><li>Ist es keine Query mit ResultSet , so erfragt getUpdateCount() die Anzahl geänderter Zeilen. </li></ul>
  7. 7. getUpdateCount() <ul><li>getUpdateCount() ergibt die Anzahl geänderten Tupel zurück. </li></ul><ul><ul><li>> 0 Es war eine UPDATE-, INSERT- oder DELETE-Operation </li></ul></ul><ul><ul><li>0 eine DDL- oder DML-Operation, die keine Tupel verändert </li></ul></ul><ul><ul><li>-1 Ergebnis ist ein ResultSet Es liegen keine Ergebnisse vor </li></ul></ul><ul><li>Alle Ergebnisse bei execute() sind ermittelt, wenn gilt: </li></ul><ul><li>getMoreResults()==false && getUpdateCount()==-1 </li></ul>
  8. 8. execute() und mehrere ResultSets <ul><li>Mit execute() kann es vorkommen, dass mehrere ResultSet s zurückkommen, etwa bei gespeicherten Prozeduren. </li></ul><ul><li>Ob es mehrere Ergebnismengen gibt, sagt getMoreResults() . </li></ul><ul><ul><li>Rückgabe ist true , wenn noch etwas folgt. </li></ul></ul><ul><ul><li>getResultSet() liefert das nächste ResultSet . </li></ul></ul><ul><li>Die Iteration kann über while() erfolgen. </li></ul><ul><li>CallableStatement s = c.prepareCall( </li></ul><ul><li> &quot;{ call MehrAlsEinResultSet }&quot; ); </li></ul><ul><li>s.execute(); </li></ul><ul><li>while( stmt.getMoreResults() ) { </li></ul><ul><li> ResultSet r = stmt.getResultSet(); </li></ul><ul><li> … </li></ul><ul><li>} </li></ul>
  9. 9. Aktualisierbare ResultSets
  10. 10. Veränderbare ResultSets <ul><li>Im Allgemeinen muss man für die Manipulation der Datensätze UPDATE-SQL-Anweisungen abschicken. </li></ul><ul><li>Mit Treiberunterstützung kann das auch ein ResultSet . </li></ul><ul><ul><li>Man kann verändern, einfügen oder löschen. </li></ul></ul><ul><li>Vorraussetzung ist ein spezielles Statement mit dem Parameter ResultSet.CONCUR_UPDATABLE . </li></ul><ul><li>Statment stmt = con.createStatement( </li></ul><ul><li> ResultSet.TYPE_SCROLL_SENSITIVE, </li></ul><ul><li> ResultSet.CONCUR_UPDATABLE ); </li></ul><ul><li>Der Standard ist CONCUR_READ_ONLY . </li></ul>
  11. 11. Kann man das ResultSet updaten? <ul><li>Bekommt man als Parameter ein ResultSet , und möchte wissen, ob man es updaten kann, liefert getConcurrency() die Antwort: </li></ul><ul><li>int concurrency = resultSet.getConcurrency() ; </li></ul><ul><li>if (concurrency == ResultSet.CONCUR_UPDATABLE) { </li></ul><ul><li> // ResultSet ist aktualisierbar </li></ul><ul><li>} else { </li></ul><ul><li> // ResultSet ist nicht aktualisierbar </li></ul><ul><li>} </li></ul>
  12. 12. Aktualisieren <ul><li>Zum Aktualisieren der Zeilen bietet das ResultSet die updateXXX() -Methoden. </li></ul><ul><ul><li>updateXXX( int n, XXX value ) aktualisiert den Wert in der Spalte n . </li></ul></ul><ul><ul><li>updateXXX( String name, XXX value ) aktualisiert den Wert in der Spalte name . </li></ul></ul><ul><li>Die Daten werden erst mit dem Aufruf von updateRow() aktualisiert. </li></ul><ul><ul><li>Die Änderungen können mit cancelRowUpdates() verworfen werden. </li></ul></ul>
  13. 13. Die erste Zeile verändern <ul><li>Statment stmt = con.createStatement( </li></ul><ul><li> ResultSet.TYPE_SCROLL_SENSITIVE, </li></ul><ul><li> ResultSet.CONCUR_UPDATABLE ); </li></ul><ul><li>ResultSet rs = stmt.executeQuery(&quot; SELECT * FROM T &quot;); </li></ul><ul><li>rs.first(); </li></ul><ul><li>rs.updateString( &quot;Spalte&quot;, &quot;Neuer Inhalt&quot; ); </li></ul><ul><li>rs.updateRow(); </li></ul>
  14. 14. Zeilen einfügen <ul><li>Um Zeilen einzufügen, erzeugt man mit moveToInsertRow() eine neue Zeile, die man dann mit den bekannten updateXXX() -Methoden füllt. </li></ul><ul><ul><li>Die Zeile nennt sich auch engl. „insert row“. </li></ul></ul><ul><ul><li>Die Daten werden erst dann übermittelt, wenn insertRow() aufgerufen wird. cancelRowUpdates() bricht die Bearbeitung ab. </li></ul></ul><ul><ul><li>Wenn der Cursor bewegt wird, wird nichts geschrieben. </li></ul></ul><ul><li> rs.moveToInsertRow(); </li></ul><ul><li> rs.updateString( 1, &quot;Shasha&quot; ); </li></ul><ul><li> rs.updateInteger( 2, 30 ); </li></ul><ul><li> rs.insertRow(); </li></ul>
  15. 15. Zeilen löschen <ul><li>deleteRow() löscht die aktuelle Zeile. </li></ul><ul><li>Um eine bestimmte Zeile zu löschen, kann man mit einer Positions-Methode den Cursor auf eine Zeile bewegen und dann löschen. </li></ul><ul><li>Beispiel: Lösche die erste Zeile. </li></ul><ul><li>rs.absolute( 1 ); </li></ul><ul><li>rs.deleteRow(); </li></ul><ul><li>Die Funktion kann nicht auf einer Einfüge-Zeile aufgerufen werden. </li></ul>
  16. 16. CONCUR_UPDATABLE, (IN)SENSITIVE <ul><li>Immer dann, wenn CONCUR_UPDATABLE gesetzt ist, bekommt man einen Cursor, der Änderungen erlaubt, egal, ob der resultSetType TYPE_FORWARD_ONLY , TYPE_SCROLL_INSENSITIVE oder TYPE_SCROLL_SENSITIVE ist. </li></ul><ul><li>Spätestens nach dem Schließen und Neuöffnen findet man alle geänderten Daten. Wichtig ist der Unterschied zwischen TYPE_SCROLL_INSENSITIVE und TYPE_SCROLL_SENSITIVE . </li></ul><ul><ul><li>TYPE_SCROLL_SENSITIVE : Erkennt beim Durchlauf die Änderungen am ResultSet und spielt den aktuellen Stand vor, auch wenn Zeilen gelöscht oder verändert wurden. </li></ul></ul><ul><ul><li>TYPE_SCROLL_INSENSITIVE : Erkennt die schon gemachten Änderungen nicht. </li></ul></ul><ul><li>Die Datenbank muss aber nicht so reagieren! </li></ul>
  17. 17. Zeile neu beziehen <ul><li>Im Fall, dass während einer längeren Abfrage sich Daten im Hintergrund ändern können, bezieht refreshRow() die Informationen neu. </li></ul><ul><li>Statement stmt = con.createStatement( </li></ul><ul><li>ResultSet.TYPE_SCROLL_SENSITIVE , </li></ul><ul><li> ResultSet.CONCUR_UPDATABLE ); </li></ul><ul><li>ResultSet rs = stmt.executeQuery(&quot;SELECT…&quot;); </li></ul><ul><li>rs.absolute( n ); </li></ul><ul><li>String s1 = rs.getString( spalte ); </li></ul><ul><li>... </li></ul><ul><li>rs.absolute( n ); </li></ul><ul><li>rs.refreshRow(); </li></ul><ul><li>String s2 = rs.getString( spalte ); </li></ul>s1 und s2 können unterschiedlich sein.
  18. 18. Batch-Verarbeitung
  19. 19. addBatch() <ul><li>Seit JDBC 2.0 können mehrere SQL-Anweisungen als Bündel an die Datenbank geschickt werden. </li></ul><ul><li>Dazu </li></ul><ul><ul><li>baut man zuerst ein Statement -Objekt auf, </li></ul></ul><ul><ul><li>fügt mit addBatch() beliebig viele SQL-Anweisungen hinzu und </li></ul></ul><ul><ul><li>führt dann mit executeBatch() die Operation aus. </li></ul></ul><ul><li>Da ein Batch kein Auto-Commit unterstützt, sollte vorher das Auto-Commit ausgeschaltet werden und erst nach dem Batch mit commit() bestätigt werden. </li></ul><ul><li>Batch-Verarbeitung funktioniert bei Statement s oder PreparedStatement s. </li></ul>
  20. 20. Batch-Beispiel mit Statement <ul><li>Connection con = ...; </li></ul><ul><li>conn.setAutoCommit( false ); </li></ul><ul><li>Statement stmt = con.createStatement(); </li></ul><ul><li>stmt.addBatch ( &quot;INSERT INTO Tabelle (..) VALUES (..)&quot; ); </li></ul><ul><li>stmt.addBatch ( &quot;INSERT INTO Tabelle (..) VALUES (..)&quot; ); </li></ul><ul><li>stmt.executeBatch(); </li></ul><ul><li>conn.commit(); </li></ul>
  21. 21. Beispiel mit PreparedStatement <ul><li>con.setAutoCommit( false ); </li></ul><ul><li>String ps = &quot;INSERT INTO Tabelle (..) VALUES (?, ?)&quot;; </li></ul><ul><li>PreparedStatement pstmt = con.prepareStatement( ps ); </li></ul><ul><li>pstmt.setXXX( 1, Wert1 ); </li></ul><ul><li>pstmt.setXXX( 2, Wert2 ); </li></ul><ul><li>pstmt.addBatch(); </li></ul><ul><li>pstmt.setXXX( 1, Wert1 ); </li></ul><ul><li>pstmt.setXXX( 2, Wert2 ); </li></ul><ul><li>pstmt.addBatch(); </li></ul><ul><li>pstmt.executeBatch(); </li></ul><ul><li>con.commit(); </li></ul>
  22. 22. Veränderte Zeilen <ul><li>Die Funktion executeBatch() liefert ein Feld von Ganzzahlen, die die Anzahl veränderten Zeilen liefern. </li></ul><ul><ul><li>Anders als bei einem normalen executeUpdate() können ja mehrere unterschiedliche Befehle kombiniert werden. </li></ul></ul><ul><li>int[] updateCounts = pstmt.executeBatch() ; </li></ul>
  23. 23. Fehlerbehandlung <ul><li>Falls im Batch-Prozess etwas schief läuft, gibt es eine BatchUpdateException . </li></ul><ul><li>Hier muss man wieder eine korrekte Transaktions-Steuerung implementieren: </li></ul><ul><li>try { </li></ul><ul><li> con.setAutoCommit( false ); </li></ul><ul><li> // Batch aufbauen und sammeln </li></ul><ul><li> int[] updateCounts = pstmt.executeBatch(); </li></ul><ul><li> con.commit(); </li></ul><ul><li>} catch ( BatchUpdateException e ) { </li></ul><ul><li> con.rollback(); </li></ul><ul><li>} catch ( SQLException e ) { ... } </li></ul>
  24. 24. Veränderte Zeilen bei Exception <ul><li>Wird executeBatch() aufgerufen und eine BatchUpdateException folgt, kann man sich für die übrig gebliebenen SQL-Anweisung aus dem Exception-Objekt die übrige Anzahl modifizierter Zeilen holen: </li></ul><ul><li>try { </li></ul><ul><li> ... </li></ul><ul><li> int[] updateCounts = pstmt.executeBatch(); </li></ul><ul><li> ... </li></ul><ul><li>} catch ( BatchUpdateException e ) { </li></ul><ul><li> int[] updateCounts = e.getUpdateCounts(); </li></ul><ul><li> ... </li></ul><ul><li>} </li></ul>
  25. 25. getUpdateCounts() <ul><li>Die Funktion e.getUpdateCounts() liefert im Feld noch andere Informationen: </li></ul><ul><li>int[] updateCounts = e.getUpdateCounts(); </li></ul><ul><li>Ist </li></ul><ul><ul><li>updateCounts[i] >= 0 , dann steht der Wert für die veränderten Zeilen. </li></ul></ul><ul><ul><li>updateCounts[i] == Statement.SUCCESS_NO_INFO (-2), dann ist die Anzahl veränderter Zeilen nicht sichtbar. </li></ul></ul><ul><ul><li>updateCounts[i] == Statement.EXECUTE_FAILED (-3), dann ist ein Fehler hier aufgetreten. </li></ul></ul>
  26. 26. Professionelle IT-Qualifizierung
  27. 27. tutego über tutego <ul><li>Inhouse-Schulungen mit individualisierten Inhalten und Terminauswahl </li></ul><ul><li>190 Seminare </li></ul><ul><li>Kernkompetenz Java (60 Themen) </li></ul><ul><li>Europaweit führende Position im Bereich Java-Schulungen </li></ul><ul><li>Hochqualifizierte und zertifizierte Referenten </li></ul><ul><li>Firmengründung 1997 durch Java Champion Christian Ullenboom </li></ul>
  28. 28. Unsere Themen
  29. 29. Unsere Themen

×