SQL Update COMMAND

  • VB.NET

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

    SQL Update COMMAND

    Hallo an alle,

    undzwar habe ich einen Update COmmand der alleridings nicht akzeptiert wird, bin jetzt nicht so der große SQL-Profi.

    Wo liegt denn der Fehler??

    VB.NET-Quellcode

    1. Dim sql_update_query As String = "Update user_accounts Set password = " + TextBoxPasswortNew.Text + "where Benutzername = " + TextboxUser.Text


    Spoiler anzeigen

    Hier noch mei kompletter Code:

    VB.NET-Quellcode

    1. Private Sub sql_update()
    2. Dim conn As New SqlClient.SqlConnection
    3. Dim myCommand As New SqlClient.SqlCommand
    4. Dim myAdapter As New SqlClient.SqlDataAdapter
    5. Dim myData As New DataTable
    6. Dim sql_update_query As String = "Update user_accounts Set password = " + TextBoxPasswortNew.Text + "where Benutzername = admin"
    7. conn.ConnectionString = "Data Source=.\SQLExpress;Integrated Security=true; AttachDbFilename=|DataDirectory|\SQL_ESBE-USER.mdf;User Instance=true;"
    8. Try
    9. conn.Open()
    10. Try
    11. myCommand.Connection = conn
    12. myCommand.CommandText = sql_update_query
    13. myAdapter.SelectCommand = myCommand
    14. myAdapter.Fill(myData)
    15. Catch dbreaderror As SqlClient.SqlException
    16. MessageBox.Show("Fehler beim Aktualisieren der Datenbank: " & dbreaderror.Message)
    17. End Try
    18. Catch dbconnerror As SqlClient.SqlException
    19. MessageBox.Show("Fehler beim Verbinden mit der Datenbank: " & dbconnerror.Message)
    20. Finally
    21. If conn.State <> ConnectionState.Closed Then conn.Close()
    22. End Try
    23. End Sub

    user_accounts ist meine Tabelle, password ist eine Spalte, Benutzername ist auch eine Spalte.

    Spalte Password soll dort ersetzt werden wo der Benutzername aus der TextboxUser übereinstimmt.

    Gruß

    Habs dann mal selbst gelöst :)

    Hier der Code:

    VB.NET-Quellcode

    1. Private Sub sql_update()
    2. Dim conn As New SqlClient.SqlConnection
    3. Dim myCommand As New SqlClient.SqlCommand
    4. Dim myAdapter As New SqlClient.SqlDataAdapter
    5. Dim myData As New DataTable
    6. Dim SQL As String = "UPDATE User_Accounts SET Password = " + TextBoxPasswortNew.Text + " WHERE " + TextBoxUserName.Text + " = Benutzername "
    7. Dim SQL_Update As String = "UPDATE User_Accounts Set Password = " + TextBoxPasswortOld.Text + " Where Benutzername = " + TextBoxUserName.Text
    8. conn.ConnectionString = "Data Source=.\SQLExpress;Integrated Security=true; AttachDbFilename=|DataDirectory|\SQL_ESBE-USER.mdf;User Instance=true;"
    9. Dim sql_update_query As String = "UPDATE user_accounts SET password = '" & TextBoxPasswortNew.Text & "' WHERE benutzername = '" & TextBoxUserName.Text & "'"
    10. Try
    11. conn.Open()
    12. Try
    13. myCommand.Connection = conn
    14. myCommand.CommandText = sql_update_query
    15. myAdapter.SelectCommand = myCommand
    16. myAdapter.Fill(myData)
    17. Catch dbreaderror As SqlClient.SqlException
    18. MessageBox.Show("Fehler beim Aktualisieren der Datenbank: " & dbreaderror.Message)
    19. End Try
    20. Catch dbconnerror As SqlClient.SqlException
    21. MessageBox.Show("Fehler beim Verbinden mit der Datenbank: " & dbconnerror.Message)
    22. Finally
    23. If conn.State <> ConnectionState.Closed Then conn.Close()
    24. End Try
    25. End Sub


    habe beim Update-Command die Hochkommas vergessen und + statt & verwendet.
    Also von der SQL Syntax siehts richtig aus
    ist Benutzername dein Primary Key?
    Wenn ja gut, wenn nein würde dir diese Veränderung zu lasten fallen. Weil du dann die Passwörter von mehreren Benutzern änderst die den gleichen Namen haben ;)

    SQL Syntax müsste richtig sein

    EDIT:// Dir fehlt das Semikolon ";" nach dem Befehl ;)

    VB.NET-Quellcode

    1. Dim SQL As String = "UPDATE User_Accounts SET Password = " + TextBoxPasswortNew.Text + " WHERE " + TextBoxUserName.Text + " = Benutzername "

    SQL-Abfrage

    1. UPDATE User_Accounts SET Password = TextBoxPasswortNew.Text
    2. WHERE TextBoxUserName.Text = Benutzername
    3. # Benutzername muss links vom gleichheitszeichen stehen!
    4. # Semikolon ";" fehlt auch da
    Ja es ging mir nur um die eindeutigkeit ;)
    Aber wie gesagt.
    dir Fehlt das Semikolon und dann noch ein Fehler das ich oben nochmal dazugeschrieben habe

    Würde auch die Aneinanderreihung vom String mit & machen und nicht mit +

    (Du kannst auch alle Passwörter zusammen ändern)



    SQL-Abfrage

    1. UPDATE User_accounts SET Password = 12345
    2. # Alle User haben das Passwort '12345'
    Wo meinst du das denn, mit dem Semikolon. Hinter Benutzername?

    Aber so wie der Code jetzt ist, da oben funktioniert er einwandfrei im Programm.
    Benutzername habe ich doch links vom = stehen. Weil der Benutzername soll ja gleich mit dem TextBox Inhalt sein.
    In allen gängigen Programmiersprachen setzt man am Ende eines Befehls ein Semikolon damit der Computer die Befehle abgrenzen kann.

    Bei VB wurde das mit dem Semikolon weggelassen. Wieso weiß ich auch nicht. Aber VB ließt ein Befehl anhand einer Zeile. Es sei denn es ist eine If-Abfrage oder so deswegen End If und so.
    also die DELETE-Syntax lautet so

    Inhalte löschen:

    SQL-Abfrage

    1. DELETE FROM user_accounts WHERE benutzername = 'Solaris';


    Tabelle löschen:

    SQL-Abfrage

    1. set foreign_key_checks = 0;
    2. DROP table user_accounts IF EXISTS;
    3. set foreign_key_checks = 1;

    xXAlphaXx schrieb:


    dir Fehlt das Semikolon ...


    Das Semikolon wird in SQL nur benötigt wenn man mehrere SQL-Statements (Statements und nicht Befehle da ein SQL-Statement aus mehreren 'Befehlen' - besser SQL-Schlüsselwörter/-Funktionen - bestehen kann ... z.B. Abfrage mit Sub-Selects) als Batch-/Stapel-Verarbeitung aneinander reihen möchte.

    Will man nur ein Statement abarbeiten kann man sich das Semikolon auch sparen.

    @ dbsystel

    Es ist ganz einfach zu merken:

    Werte vom Typ TEXT müssen IMMER Hochkommas (') eingefasst werden.

    Werte vom Type Zahl/Numeric brauchen überhaupt kein Literal.

    Werte vom Typ-Datum müssen immer mit dem Datums-Literal (#) eingefasst werden.

    xXAlphaXx hat allerdings Recht wenn er anmerkt das "Name" NIEMALS eine eindeutige Bezeichnung für einen Datensatz sein kann. Zu schnell hast Du zwei verschiedene Müller oder Meier als User und dann versagt Deine komplette User-Abfrage. Spätestens wenn Du Name als Primary Key gekennzeichnet hast und Du einen zweiten Müller oder Meier anlegen willst war es das mit Deinem Daten-Modell.

    Und eindeutig Nein ... nur weil es heute so ist das kein Name zweimal vorkommt, muss das nicht heissen das es nicht in Zukunft Namen geben kann die zweimal vorkommen.

    Daher IMMER eindeutige Bezeichner wählen, z.B. Zahlenwerte. Das hat auch den Vorteil das Namensänderungen (z.B. User Frau Brechtfeld heiratet und heisst danach Frau Müller) auch nie die eindeutige Identifizierung verletzen können.

    Also kurz: Alle Eigenschaften (Nachnamen, Vornamen, Geburtsdatum oder auch Kombinationen daraus) einer Entität sind völlig ungeeignet um als Unique Identifier zu fungieren. Das würde ich Dir dringend ans Herzen legen zu verinnerlichen ... ein Unique Identifier MUSS IMMER und unter JEDEM Umstand einzigartig sein und es dürfen keine Umstände auftreten können die ein Veränderungen erfordern. Daher ist es auch eine dumme Idee z.B. Artikelnummern bei einer Artikelverwaltung als Unique Identifier her zu nehmen, obwohl sie einzigartig sind aber sie können sich ändern ... eine Firma kann halt mal auf die Idee kommen nach x-Jahren einen neuen Standard für Artikelnummern einzuführen.

    Gruß

    Rainer
    Hallo Rainer,
    erstmal Danke für die Erklärung bezgl. SQL.

    Aber es ist in meinem Prog so, das ein Benutzername aus Vorname+Nachname+letzten 2 Ziffern vom Geurtsjahr besteht.
    So sollte doch eig. kein Problem entstehen.
    Zumal wird beim Erstellen von neuen Usern auch überprüft ob dieser Name schon besteht und wenn ja, das dieser nicht akzeptiert wird und ein anderer gewählt werden muss.
    Hier zur Kontrolle mein Code zur Überprüfung(mit LiNQ)

    VB.NET-Quellcode

    1. Dim Check = From SQL_ESBE_User In user_exist.User_Accounts _
    2. Where BenutzernameTextBox.Text = SQL_ESBE_User.Benutzername
    3. If Not Check.Count = 0 Then
    4. MsgBox("Der gewünschte Benutzername ist schon vorhanden!" + vbNewLine + "Bitte wählen sie einen anderen!")
    5. BenutzernameTextBox.Clear()
    6. BenutzernameTextBox.Focus()
    7. Else
    8. Me.Validate()
    9. Me.User_AccountsBindingSource.EndEdit()
    10. Me.TableAdapterManager.UpdateAll(Me._SQL_ESBE_USERDataSet)
    11. End If


    Gruß
    Christopher

    dbsystel schrieb:

    Aber es ist in meinem Prog so, das ein Benutzername aus Vorname+Nachname+letzten 2 Ziffern vom Geurtsjahr besteht.
    So sollte doch eig. kein Problem entstehen.


    Und genau das ist kompletter "Unfug". ;)

    Müller, Franz geb. 16.05.1967
    Müller, Franz geb. 18.08.1967

    Wären in Deinem Fall dann ein und derselbe Benutzer und doch sind es unterschiedliche Personen. Natürlich ist das nur sehr theoretisch (aber auch je größer die Nutzeranzahl desto wahrscheinlicher), aber da es aber in der Theorie möglich ist das das vorkommt ist Deine Wahl eindeutig kein Unique Identifier, bzw. eindeutig kein sinnvoller Schlüssel für die Tabelle.

    Vor allem überleg auch mal das Du möglicherweise diese ID noch als FK/Bezugs-Punkt in anderen Tables verwenden willst ... wie sind die Auswirkungen wenn Du auf einmal den PK des Tables abändern müsstest z.B. weil Namensänderung auf Grund Heirat oder auch einfach nur weil im Nachgang auffällt das der User mit falschen Daten angelegt wurde.

    Hast Du aber einen künstlich erzeugen PK (z.B. Zahlenwerte ab 1 afwärts zählend pro User) kann Dir das alles völlig egal sein. User mit der ID 2 wird egal wie oft sich seine Daten ändern und wie häufig sein Name doppelt vorkommt immer eindeutig als User 2 zu identifizieren sein.

    Gewöhn Dir sowas also bitte dringendst ab. Das ist absolut tödlich, denn je öfters Du so einen Unfug machst desto höher die Wahrscheinlichkeit das der theoretische Worst-Case auch in der Praxis eintritt und dann ist oftmals das Modell für den Allerwertesten und man muss es neu aufziehen/programmieren.

    Und nein ... das ist nicht nur eine theoretische Diskussion ohne Praxis-Auswirkungen, sondern das ist Praxis-Erfahrung und daher auch das theoretische Grundprinzip das Unique Identifiers/Primary Keys IMMER künstlich sein sollten und NIEMALS einen Bezug zu realen Daten aufweisen dürfen.

    Aber natürlich ... Deine DB und Deine Entscheidung was Du machst. ;)

    Gruß

    Rainer
    Hi,
    nochmals Danke für die ausführliche Textung hier.

    Ich verstehe schon wie du das meinst, aktuell für mein Programm ist das nicht wichtig, aber für neue folgende Progs schon.
    Wie kann ich denn das einstellen, das automatisch ein Wert im TextBoxUserID Feld um 1 erhöht wird, so das ich eine eindeutige ID kriege die dann auch nur einmal da ist??


    Gruß

    dbsystel schrieb:

    Ich verstehe schon wie du das meinst, aktuell für mein Programm ist das nicht wichtig, aber für neue folgende Progs schon.

    Was noch nicht angeführt wurde ist, dass es absolut nichts schadet, es von anfang an richtig zu machen, und der mehraufwand bemisst sich in wenigen minuten.
    Vorteil einer "Best Practice" ist einerseits, dass man nicht jedesmal neu nachdenkt, sondern es ist ein Standard, den man ausführt, wie man sich die Schnürsenkel bei Schuhe anziehen bindet.
    Weiterer Vorteil ist, dass du dich in 3 Jahren nicht wunderst, was fürn schrulliges Zeugs du dir damals wohl zurechtgefrickelt haben magst.

    Noch ein paar Hinweise:
    AvoidTryCatch trifft auch hier zu. Die von dir angezeigte Messagebox ist zB. gleich mal schlicht falsch - ein Fehler von Fill(myData) hat mit einer Aktualisierung der DB nix zu tun.
    Aber "bessere" das lieber nicht nach, sondern nimm es raus, denn eine Messagebox ist nahezu nie eine Fehlerbehandlung in dem Sinne, dass verantwortet werden kann, dass das Prog anschließend weiter laufen darf (was es bei dir ja täte).

    Dann empfehle ich, mit gescheit typisierten Objekten zu proggen, nicht mit einer untypisierten DataTable.
    Generiere dir unbedingt ein typisiertes Dataset, sodaß ein Datumswert von vornherein auch den Typ DateTime hat, ein Integer ein Integer ist, Bool - Bool etc, und du nicht bei jeder Verwendung schreibfehleranfällige String-Schlüssel benutzen musst, und Casts, die sich auch irren können.
    Für relativ einfache Anforderungen ists sogar noch einfacher, die Datenbank erstmal wegzulassen, gugge DB-Programmierung ohne Datenbank
    Ein typisiertes Dataset gibt dir auch Gestaltungsmöglichkeiten im Designer an die Hand (etwa für Datagridviews, aber auch alle möglichen anderen Controls) deren Einfachheit und Mächtigkeit du dir nicht vorstellen kannst, wenn dus noch nicht gesehen hast (und davon gehe ichmal aus).

    Falls du auf einem handprogrammierten DB-Zugriff bestehst, empfehle ich dir die CommandBuilder-Klasse. Die kann aus einem SELECT - Command selbständig die Commands für INSERT, UPDATE und DELETE generieren - gugge CommandBuilderSample