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.230 Aufrufe

Veröffentlicht am

Veröffentlicht in: Technologie
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

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

Keine Downloads
Aufrufe
Aufrufe insgesamt
2.230
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
226
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie
  • #toc1
  • #index executeUpdate(), Statement
  • #toc2
  • #index getResultSet(), Statement #index getUpdateCount(), Statement
  • #index getUpdateCount(), Statement
  • #index getMoreResults(), Statement
  • #toc2
  • #index ResultSet.TYPE_SCROLL_SENSITIVE #index ResultSet.CONCUR_UPDATABLE
  • #index getConcurrency(), ResultSet
  • #index updateRow(), ResultSet #index cancelRowUpdates(), ResultSet
  • #index moveToInsertRow() , ResultSet #index cancelRowUpdates() , ResultSet #index insertRow() , ResultSet
  • #index deleteRow(), ResultSet
  • #index refreshRow(), ResultSet
  • #toc2
  • #index addBatch(), Statement #index executeBatch(), Statement
  • #index BatchUpdateException #index getUpdateCounts(), BatchUpdateException
  • #index getUpdateCounts(), BatchUpdateException
  • 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

    ×