Update aktualisert die falsche Zeile

  • VB.NET

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Update aktualisert die falsche Zeile

    Moin,

    mit diesem Befehl möchte ich einen Datensatz in einer Accessdatenbank aktualisieren

    VB.NET-Quellcode

    1. Dim sql As String = "UPDATE tblPosition SET tblRechnungID = @tblRechnungID, Artikel = @Artikel, Beschreibung = @Beschreibung, SellerAssignedID = @SellerAssignedID, BuyerAssignedID = @BuyerAssignedID, UnitQuantity = @UnitQuantity, TaxPercent = @TaxPercent, TypeCode = @TypeCode, CategoryCode = @CategoryCode, NetUnitPrice = @NetUnitPrice, GrossUnitPrice = @GrossUnitPrice , UnitCode = @UnitCode WHERE tblPositionID = @PositionId"
    2. Using conn As New OleDbConnection(connString)
    3. conn.Open()
    4. Using comm As New OleDbCommand(sql, conn)
    5. comm.Parameters.Add("@tblRechnungID", OleDbType.Integer).Value = tblRechnungID
    6. comm.Parameters.Add("@Artikel", OleDbType.Char).Value = Artikel
    7. comm.Parameters.Add("@Beschreibung", OleDbType.Char).Value = Beschreibung
    8. comm.Parameters.Add("@SellerAssignedID", OleDbType.Char).Value = SellerAssignedID
    9. comm.Parameters.Add("@BuyerAssignedID", OleDbType.Char).Value = BuyerAssignedID
    10. comm.Parameters.Add("@UnitQuantity", OleDbType.Double).Value = UnitQuantity
    11. comm.Parameters.Add("@TaxPercent", OleDbType.Double).Value = TaxPercent
    12. comm.Parameters.Add("@TypeCode", OleDbType.Integer).Value = TypeCode
    13. comm.Parameters.Add("@CategoryCode", OleDbType.Integer).Value = CategoryCode
    14. comm.Parameters.Add("@NetUnitPrice", OleDbType.Double).Value = NetUnitPrice
    15. comm.Parameters.Add("@GrossUnitPrice", OleDbType.Double).Value = GrossUnitPrice
    16. comm.Parameters.Add("@UnitCode", OleDbType.Integer).Value = UnitCode
    17. comm.Parameters.Add("@cuserid", OleDbType.Integer).Value = actualUserID
    18. comm.Parameters.Add("@PositionId", OleDbType.Integer).Value = PositionID
    19. Debug.Print(GetFullCommandSQL(comm))
    20. Debug.Print(comm.ExecuteNonQuery())
    21. End Using
    22. End Using


    Der Code aktualisiert immer den ersten Datensatz der Datentabelle egal welchen Wert ich für tblPositionID, den Primärschlüssel der Tabelle, eingebe und ich verstehe nicht warum.
    In Zeile 19 wird dieser SQL-Code ausgegeben.

    SQL-Abfrage

    1. UPDATE tblPosition SET tblRechnungID = 3, Artikel = 'Artikel', Beschreibung = 'Beschreibung', SellerAssignedID = 'Seller', BuyerAssignedID = 'Buyer', UnitQuantity = 2, TaxPercent = 19, TypeCode = 53, CategoryCode = 19, NetUnitPrice = 10, GrossUnitPrice = 20 , UnitCode = 1 WHERE tblPositionID = 2

    In Access direkt eingegeben, wird die richtige Zeile aktualisert, im Code immer die erste, egal welchen Wert ich für tblPositionID angebe.
    Mit anderen Updates mit analogen Routinen funktioniert es.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    GetFullCommandSQL ist selbstgebastelt oder? Daher wird das wenig Aufschluss darüber geben, was genau passiert. Hast du auch in Zeile 20 mal angehalten und geschaut, ob der Wert von tblPosition immer noch 2 ist?
    Nicht dass da irgendwas komisches passiert in der GetFullCommandSQL

    Ich glaube es liegt an dem OleDbCommand. Da gabs hier schonmal Problem mit Parameters, mal gucken ob ich das wieder finde.
    Kannst du ein Command verwenden, das auf die DB zugeschnitten ist? Z.B Microsoft.Data.SqlClient.SqlCommand für MSSQL, ich weiß nicht ob Access sowas hat.
    Die Funktion ​GetFullCommandSQL ist es nicht. Die ist nur eine Hilfsfunktion, die ich nutze um den SQL-Code zu sehen.

    VB.NET-Quellcode

    1. Public Function GetFullCommandSQL(cmd As OleDbCommand) As String
    2. Dim sql As String = cmd.CommandText
    3. For Each p As Data.Common.DbParameter In cmd.Parameters
    4. If sql.Contains(p.ParameterName) AndAlso p.Value IsNot Nothing Then
    5. If p.Value.GetType Is GetType(String) Then
    6. sql = sql.Replace(p.ParameterName,
    7. String.Format("'{0}'", p.Value.ToString))
    8. Else
    9. sql = sql.Replace(p.ParameterName, p.Value.ToString)
    10. End If
    11. End If
    12. Next
    13. Return sql
    14. End Function
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Versuch mal

    VB.NET-Quellcode

    1. Dim sql As String = "UPDATE tblPosition SET tblRechnungID = ?, Artikel = ?, Beschreibung = ?, SellerAssignedID = ?, BuyerAssignedID = ?, UnitQuantity = ?, TaxPercent = ?, TypeCode = ?, CategoryCode = ?, NetUnitPrice = ?, GrossUnitPrice = ? , UnitCode = ? WHERE tblPositionID = ?"
    Damit geht die GetFullCommandSQL natürlich erstmal nicht mehr.
    Versuch auch die AddWithValue Methode
    Moin ich habe den Fehler gefunden.

    Es war eine C&P Fehler.

    Die Zeile 17 versucht einen Parameter zuzuweisen, der gar nicht im SQL-Statement vorkommt. Dieser der Wert von actualUserID ist 1, deshalb wurde der erste Datensatz geändert.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Dann scheinen die Namen in Access ja wirklich nicht berücksichtigt zu werden.

    Wenn du dann dennoch die Fragezeichen versuchst, lässt sich deine GetFullCommand verkürzen. Und ich denke (habs aber nicht getestet) die würde in diesem Fall sogar den fehlerhaften SqlString anzeigen, wo immer die 1 drinsteht.

    VB.NET-Quellcode

    1. Public Function GetFullCommandSQL(cmd As OleDbCommand) As String
    2. Dim sql = cmd.CommandText.Split("?"c)
    3. Return String.Join(String.Empty, sql.Zip(cmd.Parameters.Cast(Of OleDbCommand), Function(sec, par) sec & If(TypeOf par.Value Is String, $"'{par.Value}'", par.Value.ToString))) & sql.Last
    4. End Function