Auslesen des neuen Wertes der Schlüsselspalte nach dem Erstellen eines neuen Datensatzes mit @@Identity

    • Allgemein

    Es gibt 3 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

      Auslesen des neuen Wertes der Schlüsselspalte nach dem Erstellen eines neuen Datensatzes mit @@Identity

      Wenn man den neuen Wert einer Schlüsselspalte nach dem Einfügen erhlten möchte, bietet sich der SQL-Befehl @@Identity an.

      Als Beispiel wird einen Verbindung zu einer Access-Datenbank genutzt:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System.Data.OleDb
      2. Public Class frmTest
      3. .....
      4. Private Function SpeichernMitNeuemWert() as int64
      5. Dim MeinSqlConnection As OleDbConnection = New OleDbConnection(My.Settings.DBConnectionString)
      6. 'Speichern
      7. Dim MeinSqlString As String = "INSERT INTO Tabelle(Feld1,Feld2, ....) VALUES (Wert1,Wert2,....)"
      8. Dim MeinSqlCommand As OleDbCommand = New OleDbCommand(MeinSqlString, MeinSqlConnection)
      9. MeinSqlConnection.Open()
      10. Try
      11. MeinSqlCommand.ExecuteNonQuery()
      12. Catch ex As Exception
      13. MessageBox.Show(ex.Message)
      14. End Try
      15. 'ID-Wert auslesen
      16. MeinSqlString = "Select @@Identity From tTest"
      17. MeinSqlCommand.CommandText = MeinSqlString
      18. Try
      19. Wert = MeinSqlCommand.ExecuteScalar
      20. Catch ex As Exception
      21. MessageBox.Show(ex.Message)
      22. End Try
      23. MeinSqlConnection.Close()
      24. Return Wert
      25. End Function
      26. .....
      27. End Class



      Falls ein anderer Datenbanktyp verwendet werden soll, muss die DLL, die den Zugriff auf die Datenbank steuert ausgetauscht werden.
      Dazu muss dann überall im Code OleDB durch die entspechende Information ersetzt werden.
      z.B. für den Zugriff auf MS SQL-Server bzw. MS SQL.ServerExpress OleDB durch SQL

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System.Data.SQLClient
      2. Public Class frmTest
      3. .....
      4. Private Function SpeichernMitNeuemWert() As Int64
      5. Dim MeinSqlConnection As SQLConnection = New SQLConnection(My.Settings.DBConnectionString)
      6. 'Speichern
      7. Dim MeinSqlString As String = "INSERT INTO Tabelle(Feld1,Feld2, ....) VALUES (Wert1,Wert2,....)"
      8. Dim MeinSqlCommand As SQLCommand = New SQLCommand(MeinSqlString, MeinSqlConnection)
      9. MeinSqlConnection.Open()
      10. Try
      11. MeinSqlCommand.ExecuteNonQuery()
      12. Catch ex As Exception
      13. MessageBox.Show(ex.Message)
      14. End Try
      15. 'ID-Wert auslesen
      16. MeinSqlString = "Select @@Identity From tTest"
      17. MeinSqlCommand.CommandText = MeinSqlString
      18. Try
      19. Wert = MeinSqlCommand.ExecuteScalar
      20. Catch ex As Exception
      21. MessageBox.Show(ex.Message)
      22. End Try
      23. MeinSqlConnection.Close()
      24. Return Wert
      25. End Function
      26. .....
      27. End Class

      NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „INOPIAE“ ()

      Anwendung bei der Befüllung von Tabellen im typisierten Dataset

      Hi!

      Ich hatte eiglich vor, selbst ein Snippet zum Thema einzustellen, finde aber, es passt ausgezeichnet hier als Anhang:

      VB.NET-Quellcode

      1. Imports System.Data.OleDb
      2. Namespace MAAutoWertDataSetTableAdapters
      3. Partial Public Class MitarbeiterTableAdapter
      4. Private _IdentityCommand As New OleDbCommand("SELECT @@IDENTITY")
      5. Private Sub Adapter_RowUpdated(ByVal sender As Object, ByVal e As OleDbRowUpdatedEventArgs) Handles _adapter.RowUpdated
      6. If e.StatementType = StatementType.Insert Then
      7. _IdentityCommand.Connection = e.Command.Connection
      8. _IdentityCommand.Transaction = e.Command.Transaction
      9. e.Row(e.Row.Table.PrimaryKey(0)) = _IdentityCommand.ExecuteScalar()
      10. End If
      11. End Sub
      12. End Class
      13. End Namespace
      Hier ist das Command, mit welchem die Identity geholt wird ins DataAdapter_RowUpdated - Event eines typisierten TableAdapters gelegt.
      Wenn nun der TableAdapter eine DataTable updated, fragt er bei Insert-Commands gleich den von der DB generierten Primkey ab, und pflegt ihn in die soeben abgespeicherte DataRow ein, sodasser im weiteren sofort im Dataset verfügbar ist.
      Dateien
      • UpdateDB.zip

        (156,65 kB, 286 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

      Hallo Erfinder,

      ich habe jetzt ein Testprojekt erstellt und eine Datenbank eingebunden.
      Wenn ich nun deinen Codeschnipsel in den Code des DataSet einfüge, bekomme ich eine Fehlermeldung, dass die Handles Klausel ein WithEvent benötigt.
      Ich habe in der MAAutoWertDataSet.Designer.vb gesehen, dass dort auch noch was eingetragen wurde, dort auch das WithEvent.
      Wird das dort nicht alles automatisch eingetragen oder wie genau kann ich deinen Code ans Laufen bekommen ?

      Gruß
      HerrFrie

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „HerrFrie“ ()

      Das Einfügen des CodeSchnippels erfordert ein Verständnis von partialen Klassen.

      Bei partialen Klassen wird der Code einer Klasse auf mehrere Dateien aufgeteilt. Ein Beispiel was jeder kennt benutzt, ist der Form-User-Code, wo man üblicherweise die Eventhandler von Button-Klicks etc. implementiert.
      Die Datei, die man durch doppelklick im Designer auf einen Button öffnet, ist nur die Teil-Klasse des gesamten Forms. Der annere Teil befindet sich in der Datei "Form1.Designer.vb"

      Und genauso geht man am besten auch vor, wenn man einen generierten TableAdapter um das Row_Updated-Ereignis erweitern möchte:
      Im Dataset-Designer auf den TableAdapter doppelklicken, sodaß man in den UserCode des Datasets kommt.

      Ist bischen komplexer, denn in dieser User-Code-Datei können mehrere partiale klassen angelegt sein. DoppelKlickst man etwa auf eine DataTable, so wird das DataTable_RowChanging-Event generiert, in der Partialen Klasse der gedoppelklicksten DataTable.

      Also auf den typisierten TableAdapter doppelklicksen, und dort den gezeigten Code in die dadurch generierte partiale TableAdapter-Klasse einpasten.
      Denn nur innerhalb der partialen Klasse des TableAdapters besteht zugriff auf die WithEvents-Variable "_adapter".