MySqlConnector/NET Create User mit PeparedStatement

  • VB.NET
  • .NET (FX) 4.0

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    MySqlConnector/NET Create User mit PeparedStatement

    Ich verwende den MySqlConnector/NET um User in einer Datenbank zu erstellen:

    VB.NET-Quellcode

    1. Using Connection = New MySql.Data.MySqlClient.MySqlConnection(New MySql.Data.MySqlClient.MySqlConnectionStringBuilder() With { _
    2. .Server = "localhost", _
    3. .CharacterSet = "utf8", _
    4. .SslMode = MySql.Data.MySqlClient.MySqlSslMode.Preferred, _
    5. .Password = "Geheim", _
    6. .UserID = "root"}.ConnectionString)
    7. Connection.Open()
    8. Using Command = Connection.CreateCommand
    9. Command.CommandText = "CREATE USER 'Niko'@'localhost' IDENTIFIED BY @Password;"
    10. Command.Prepare()
    11. Command.Parameters.AddWithValue("@Password", "Geheim")
    12. Command.ExecuteNonQuery()
    13. End Using
    14. End Using

    Das funktioniert problemlos und der User wird so erstellt.
    Aber jetzt möchte ich, dass der User-Name und der Host so wie das Passwort aus einer Variable kommt. Der User-Name wird aus anderen Daten, die in Textboxen eingegeben werden, zusammengestellt, also ich kann das nicht einfach in den Query-String einfügen.
    Das Problem ist, ich weiß nicht, wie ich die beiden Teile angeben soll.
    Mit dem User-Name alleine funktioniert es so:

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER @Name IDENTIFIED BY @Password;"
    2. Command.Parameters.AddWithValue("@Name", "Niko")
    Und das erstellt einen User Niko mit dem Host %, also da muss jetzt noch der Host-Teil rein.

    Folgendes hab ich probiert:

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER @Name @ @Host IDENTIFIED BY @Password;" 'bzw.
    2. Command.CommandText = "CREATE USER @Name@@Host IDENTIFIED BY @Password;" 'bzw.
    3. Command.CommandText = "CREATE USER @Name\@@Host IDENTIFIED BY @Password;"
    4. Command.Parameters.AddWithValue("@Name", "Niko")
    5. Command.Parameters.AddWithValue("@Name", "localhost")
    Alles Syntaxfehler.

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER :Name @ :Host IDENTIFIED BY :Password;" 'bzw.
    2. Command.CommandText = "CREATE USER :Name@:Host IDENTIFIED BY :Password;" 'bzw.
    3. Command.CommandText = "CREATE USER :Name\@:Host IDENTIFIED BY :Password;"
    4. Command.Parameters.AddWithValue(":Name", "Niko")
    5. Command.Parameters.AddWithValue(":Host", "localhost")
    Ebenfalls alles Syntaxfehler.

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER @Name IDENTIFIED BY @Password;"
    2. Command.Parameters.AddWithValue("@Name", "'Niko'@'localhost'") 'bzw.
    3. Command.Parameters.AddWithValue("@Name", "Niko@localhost")
    Erstellt einen User, der wortwörtlich 'Niko'@'localhost' bzw. Niko@localhost heißt mit dem Host %. War zu erwarten, aber es war einen Versuch wert.

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER '@Name'@'@Host' IDENTIFIED BY @Password;"
    2. Command.Parameters.AddWithValue("@Name", "Niko")
    3. Command.Parameters.AddWithValue("@Host", "localhost")
    "Malformed hostname (illegal symbol: '@')"

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER ':Name'@':Host' IDENTIFIED BY :Password;"
    2. Command.Parameters.AddWithValue(":Name", "Niko")
    3. Command.Parameters.AddWithValue(":Host", "localhost")
    Syntaxfehler.

    Also wie muss ich das machen?

    Es gäbe natürlich noch die Möglichkeit, direkt in die mysql.user-Tabelle einzufügen, aber das möchte ich vermeiden. Es ist auch möglich, die Namen zu escapen und direkt in den Query-String einzufügen, aber da PreparedStatements zumindest nur mit dem Namen und ohne Host funktioniert, sollte es irgendwie mit Host funktionieren.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    Zwei Sachen:
    1.) Hast du dir nach dem AddWithValue mal den Command-Text angesehen?
    2.) Nimmst du immer das selbe Command-Objekt her und wenn ja, löschst du den Inhalt der Parameter per Clear?

    Lg Radinator
    In general (across programming languages), a pointer is a number that represents a physical location in memory. A nullpointer is (almost always) one that points to 0, and is widely recognized as "not pointing to anything". Since systems have different amounts of supported memory, it doesn't always take the same number of bytes to hold that number, so we call a "native size integer" one that can hold a pointer on any particular system. - Sam Harwell
    @Radinator
    1.)
    Bei welchem Beispiel?
    1.1.) Da es sich um Prepared Statements handelt sollte sich der CommandText nicht verändern.
    Jo, ein kurzer Test hat das bestätigt:

    VB.NET-Quellcode

    1. Command.CommandText = "CREATE USER @Name IDENTIFIED BY @Password;"
    2. Helpers.DebugPrint("Vorher: " & Command.CommandText)
    3. Command.Prepare()
    4. Helpers.DebugPrint("Mitte: " & Command.CommandText)
    5. Command.Parameters.AddWithValue("@Name", "Niko")
    6. Command.Parameters.AddWithValue("@Password", "Geheim")
    7. Helpers.DebugPrint("Nachher: " & Command.CommandText)
    8. Command.ExecuteNonQuery()
    9. Helpers.DebugPrint("Ende: " & Command.CommandText)


    Vorher: CREATE USER @Name IDENTIFIED BY @Password;
    Mitte: CREATE USER @Name IDENTIFIED BY @Password;
    Nachher: CREATE USER @Name IDENTIFIED BY @Password;
    Ende: CREATE USER @Name IDENTIFIED BY @Password;


    2) Ich erstelle immer neue Command-Objekte, also ergibt sich das Problem. Aber davon abgesehen: Command.Parameters.AddWithValue zweimal mit dem selben Namen aufzurufen wirft eine Exception.
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Niko Ortner schrieb:

    Command.Prepare()
    Command.Parameters.AddWithValue("@Password", "Geheim")

    Niko Ortner schrieb:

    1.1.) Da es sich um Prepared Statements handelt sollte sich der CommandText nicht verändern.

    ?( ?( ?(
    Joar, deine Collection (SqlParameterCollection.AddWithValue) wird ja im Nachhinein geändert und .Prepare sperrt ja sozusagen die weitere Aufnahme, deswegen kann auch nichts geschehen. Oder verstehe ich das Falsch? ?(
    Deswegen müsstest du also im nachhinein, und nicht vorher, das Prepare aufrufen.
    Sobald das Prepare gefeuert wird, wird im Nachhinein keine Änderung mehr vorgenommen, ist ja eben dafür da.
    "Erstellt eine vorbereitete Version des Befehls in einer Instanz von SQL Server."


    Aber keine Ahnung wie MySQL das frisst. Musst du evtl. die Datentypen spezifizieren? Oder das Passwort in einfachem Anführungszeichen übergeben?

    Edit 14.26:
    Muss wohl so sein. Ich hab gerade bei MySQL nachgelesen.
    Option Strict On!

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Drahuverar“ ()

    Ich erlaube mir mal, hier zu pushen.

    Um es klarzustellen:
    Prepare hat ja den Vorteil, dass die Parameter nicht im CommandText stehen. Dass der CommandText durch das Angeben von Parametern nicht verändert wird ist also logisch.
    Und ja, der Prepare-Aufruf kann vor dem Setzen der Parameter geschehen. Wichtig ist: Die Parameter werden gesetzt, bevor Execute aufgerufen wird. Prepare muss nämlich nur einmal ausgeführt werden, danach kann das Command-Objekt mit unterschiedlichen Parametern weiterverwendet werden (vorausgesetzt natürlich, dass man bereits vorhandene Parameter mit Clear entfernt).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils