Mysql insert into fehler

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von schoeler.k.

    Mysql insert into fehler

    Hallo,
    wenn ich bei VB.Net einen Eintrag nur zum Testen in meine Tabelle machen will gibt er mir einen Fehler aus
    ("You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
    near 'Alter, EMail) Values ('hallo', '18', 'hallo1')' at line 1

    Ja, hier mal der Code:

    Quellcode

    1. Imports MySql
    2. Imports MySql.Data
    3. Imports MySql.Data.MySqlClient
    4. Imports System.Data.OleDb
    5. Public Class Form1
    6. Public con As New MySqlConnection
    7. Public cmd As New MySqlCommand
    8. Public reader As MySqlDataReader
    9. Public anzahl As Integer
    10. Public Sub Provider()
    11. con.ConnectionString = "server=localhost;user id=root;password=;database=Test;"
    12. cmd.Connection = con
    13. End Sub
    14. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    15. Dim Name As String = "hallo"
    16. Dim Alter As Integer = "18"
    17. Dim EMail As String = "hallo1"
    18. Try
    19. Provider() 'Verbindung zur Db öffnen
    20. con.Open()
    21. cmd.CommandText = "INSERT INTO Benutzer(Name, Alter, EMail) VALUES ('" & Name & "', '" & Alter & "', '" & EMail & "')" 'Der Befehl für die DB
    22. anzahl = cmd.ExecuteNonQuery 'anzahl enthält nun ein Wert alle geänderten/ hinzugefügten/ gelöschten Einträge
    23. con.Close() 'Verbindung zur DB schließen
    24. If anzahl > 0 Then 'Nun wird kontrolliert ob überhaupt ein Eintrag hinzugefügt geworden ist, wenn ja dann die MSG
    25. MsgBox("Sie haben einen Eintrag gemacht", MsgBoxStyle.Information)
    26. End If
    27. Catch ex As Exception
    28. con.Close() 'ich schließe hier ebenfalls die Verbindung, weil wenn ein Fehler in dem oberen code passiert, passiert er vor dem schließen der Verbindung. Wenn ich das nicht machen würde käme der Fehler das die Verbindung noch offen ist, wenn ich das nächste mal eine Verbindung öffne.
    29. MsgBox(ex.Message)
    30. End Try
    31. End Sub
    32. End Class


    Ich Danke im Voraus

    VB.NET-Quellcode

    1. Dim Alter As Integer = "18"


    Wieso die "" ?!


    Dann kann es im INSERT INTO sein, dass du dann beim Alter einen String in ein Nummernfeld reinpacken willst ?!

    Deins:

    VB.NET-Quellcode

    1. cmd.CommandText = "INSERT INTO Benutzer(Name, Alter, EMail) VALUES ('" & Name & "', '" & Alter & "', '" & EMail & "')"


    Mein Vorschlag:

    VB.NET-Quellcode

    1. cmd.CommandText = "INSERT INTO Benutzer(Name, Alter, EMail) VALUES ('" & Name & "', " & Alter & ", '" & EMail & "')"


    Mein Vorschlag zieht natürlich auch nur, wenn dein Alter Feld in der DB ein Zahlenfeld ist.
    Die "" sind irgendwie aus Gewohnheit da hin gekommen ^^
    Du hast jetz durch das Entfernen der ' ' bewirkt, dass die Zahl nicht mehr als String eingetragen wird oder?
    Das Problem besteht weiterhin.. Gleicher Fehler
    Hier nochmal der neue Code:

    Quellcode

    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2. Dim Name As String = "hallo"
    3. Dim Alter As Integer = 18
    4. Dim EMail As String = "hallo1"
    5. Try
    6. Provider() 'Verbindung zur Db öffnen
    7. con.Open()
    8. cmd.CommandText = "INSERT INTO Benutzer(Name, Alter, EMail) VALUES ('" & Name & "', " & Alter & ", '" & EMail & "')" 'Der Befehl für die DB
    9. anzahl = cmd.ExecuteNonQuery 'anzahl enthält nun ein Wert alle geänderten/ hinzugefügten/ gelöschten Einträge
    10. con.Close() 'Verbindung zur DB schließen
    11. If anzahl > 0 Then 'Nun wird kontrolliert ob überhaupt ein Eintrag hinzugefügt geworden ist, wenn ja dann die MSG
    12. MsgBox("Sie haben einen Eintrag gemacht", MsgBoxStyle.Information)
    13. End If
    14. Catch ex As Exception
    15. con.Close() 'ich schließe hier ebenfalls die Verbindung, weil wenn ein Fehler in dem oberen code passiert, passiert er vor dem schließen der Verbindung. Wenn ich das nicht machen würde käme der Fehler das die Verbindung noch offen ist, wenn ich das nächste mal eine Verbindung öffne.
    16. MsgBox(ex.Message)
    17. End Try
    18. End Sub
    Bei SQL ist das egal, da passiert die Typenkonvertierung automatisch, man kann auch in eine Integer Spalte den Wert in ' ' angeben. Das wirft noch kein Fehler aus.

    Zudem wirds ja genannt, das "near" (in der nähe von) den SQL Abschnitt der Fehler leigt und das ist meist der hintere Teil des Strings.

    Ich würde dir Raten die Spalten in ` zu packen, weil es dann nicht zu Verwechselungen kommen kann, wenn du z.B. den Spaltennamen "select" hast würde dein SQL String ja so aussehen

    SQL-Abfrage

    1. INSERT INTO Tabelle (select) VALUES ('irgendwas')


    Wie man erkennen kann würde es da zu komplikationen kommen, da "SELECT" auch ein SQL Befehl ist und man ebenefalls bei einem INSERT das auch so angeben könnte.

    Wie man das umgeht, einfach alle Namen in ` setzten oder den Tabellennamen davor schreiben, wobei ` natürlich günstiger ist, weils kürzer wird.

    SQL-Abfrage

    1. INSERT INTO `Benutzer`(`Name`, `Alter`, `EMail`) VALUES ('bla', 18, 'bla@bla.de')


    Gewöhn es dir an, erspart dir viel lästige Fehlersuche.

    Btw.: Nutze den VB-Tag für VB Code und nicht den Code-Tag. Vorteil, der VB Code lässt sich schöner lesen weil der gehighlightet wird.

    picoflop schrieb:





    Zitat von »ToMbY1234«



    Ich habe nun die Variable Alter als String Deklariert

    Völlig BESCHEUERTE "Lösung"!
    Wenn du deinen Hausschlüssel verlierst, baust du deine Haustür aus, oder besorgst dir nen neuen Schlüssel?

    Was picoflop damit meint ist, dass du realitätsnah programmieren solltest.
    Heißt Zahlen sind Zahlen und nicht Text.

    Hoffe du meintest es auch so ;)

    ToMbY1234 schrieb:

    Ich habe nun die Variable Alter als String Deklariert

    ist natürlich grad falsch herum, denn Alter ist ja wohl ein Integer, und kein String.
    Also unsauber, was heißt: zunächstmal mag es gut gehen, aber wenn du zB. mal nach Alter sortieren willst, kriegste probleme, denn Integer sortieren so:
    1
    2
    10

    und strings so
    "1"
    "10"
    "2"

    korrekte typisierung ist ein wesentliches Feature, und sollte man beachten, statt alles nach string zu konvertieren.

    Kannst auch mal in den Projekteigenschaften Option Strict On! einstellen, dann bekommst du u.U. noch mehr an schlampigen Umgang mit Datentypen als Fehler angezeigt, und kannstes beheben.
    Die Variable in VB kann sehrwohl als String deklariert sein, das ist völlig egal, sie muss später wenn man sie so in den SQL String einbaut eh zu String Konvertiert werden. Deklariert er die Variable als String so erspart er sich schonmal das Alter.ToString() beim zusammensetzten.

    Die Spalte in der DB wird sicherlicht weiterhin als Integer sein und wie gesagt, SQL macht da keine probleme wenn man ein String an eine Interger-Spalte übergibt.
    In einem SQL String hat man ja eh kaum möglichkeiten Typengerechte Variablen zu übergeben, weil es eben ein STRING ist. Das Konvertieren übernimmt dann der SQL Server der den Query verarbeitet und schaut ob der übergebene Wert sich in den Spaltentyp konvertieren lässt.
    Könnte man durchaus, aber da ichs von PHP gewohnt bin mit Querystrings zu arbeiten und DBParameter den Code in die Länge zieht, zudem der Server ja in der Lage ist das richtig zu Konvertieren, kann man ja getrost weiterhin Strings verwenden.
    Weniger Fehler als mit DBParameter kommen damit auch nicht zustande.
    Danke für den Fachausdruck 'prepared statements'.
    Bisher habe ich über mysql_real_escape_string() SQL-Injections verhindert, das andere kannte ich nicht. Aber wie ich sehe gibts das auch für PHP. Werde mir dann gleich mal meine DB-Klasse umschreiben.

    So lernt man sogar im VB Forum noch was zu PHP dazu =)

    picoflop schrieb:

    deswegen arbeitet man ja auch mit DBParameter ... ...SqlInjection...

    Ich war ein bischen unsicher, ob "Hilfreich" richtig ist, denn dem TE hilft die Bemerkung nur was, wenner recherchemäßig ziemlich auf Draht ist.
    Aber ich hab mal msdn.microsoft.com/de-de/library/ms254953.aspx rausgesucht, da kanner sich informieren.

    SqlInjection (Angriff) findet man glaub auf Wikipedia grob erklärt.
    Völlig BESCHEUERTE "Lösung"!
    Wenn du deinen Hausschlüssel verlierst, baust du deine Haustür aus, oder besorgst dir nen neuen Schlüssel?
    Wenn ich die Variable "Alter" als Integer Deklariere, dann funktioniert der MySQL Code nicht mehr..
    Ich habe das so verstanden, dass MySQL den String automatisch in einen Integer Konvertiert, wenn der String in die Integer Spalte geschrieben wird.

    Ich gebe dem Schlüsselmacher eine Rohling ( String ) und zurück bekomme ich den fertigen Schlüssel ( Integer )

    ToMbY1234 schrieb:

    Wenn ich die Variable "Alter" als Integer Deklariere, dann funktioniert der MySQL Code nicht mehr..

    Natürlich funktioniert er dann. Das Problem ist - wie oben bereits geschrieben - dass a) dein SQL Code Müll ist (wenn Alter in der DB eine Zahl ist!) und b) das ganze rumfuhrwerken mit unpassenden Datentypen noch mehr Müll ist.
    Schau dir am besten erstmal das an:
    msdn.microsoft.com/de-de/libra…oledb.oledbparameter.aspx
    Und dann arbeite in Zukunft mit parametrisierten Abfragen. Man erspart sich nämlich langfristig jede Menge Ärger damit. AUCH in anderen Sprachen ;)
    Was bei deiner Benennung auch zu Problemen führen kann ist, dass du ja so tolle Begriffe wie Alter und Name benutzt.

    Die können laut meinen Kollegen auch zu Problemen führen, da es teilweise feststehende Begriffe bei der Datenbankprogrammierung sind.
    Du kannst Alter natürlich als Integer definieren, dann musst du beim zusammensetzten jedoch den Integer wieder in einen String konvertieren oder eben die angesprochenen DBParameter nutzen.

    VB.NET-Quellcode

    1. Dim Alter As Integer = 18
    2. cmd.CommandText = "INSERT INTO `Benutzer`(`Name`, `Alter`, `EMail`) VALUES ('" & Name & "', " & Alter.ToString() & ", '" & EMail & "')"


    In VB musst du die Konvertierung noch selbst vornehmen und da der CommandText vom Typ String ist, müssen alle Datentypen zunächst nach String konvertiert werden, das hat mit dem SQL Server noch nichts am hut, erst beim Execute wird dem Server der Querystring übergeben und dann passiert die Konvertierung entsprechend der Spalten vorgaben.

    @schoeler.k: Genau das war ja auch das Problem, was man jedoch umgeht indem man den Namen in ` ` setzt.