Variablen in SQLite schreiben (INSERT)

  • Hallo zusammen,

    ich habe eine vermutlich sehr einfach zu beantwortende Frage, aber gefühlt habe ich jetzt des Internet durchgelesen und finde die Antwort nicht. Ich habe eine einfache GUI gebaut (ID, Vorname, Name, Telefonnummer) und möchte die Daten in eine SQLite Datenbank schreiben. Die GUI funktioniert, das Schreiben in die DB auch. Allerdings werden meine Variablen nicht in die DB geschrieben. Der Codeteil, um den es geht:

    Code
    Func Button1Click()
       $Vorname=GUICtrlRead($Input2)
       $Name=GUICtrlRead($Input3)
       $Telefon=GUICtrlRead($Input4)
       ConsoleWrite($Vorname & $Name & $Telefon)
       _SQLite_Exec($DB, "INSERT INTO Tabelle (Name, Vorname, Summe) Values ($Vorname, $Name, $Telefon)")
       _SQLite_Exec($DB, "INSERT INTO Tabelle (Name, Vorname, Summe) Values ('Esseling', 'Holger', '0251-908070')")
       EndFunc
    Func Button2Click()

    Den unteren INSERT-Befehl führt er aus, den oberen auch - aber es werden leere Felder in der DB angelegt. Ich habe hier schon alle möglichen Syntax-Varianten probiert, verstehe aber einfach nicht, warum er die Variablen anstatt von Text nicht annimmt. Über sachdienliche Hinweise freue ich mich sehr!

    Herzliche Grüße

    Holger

  • Hallo :)

    Alles zwischen den " (double quotes) wird als String gewertet.

    Es ist also ab dem Moment kein Code mehr, sondern einfach nur Text, der in eine Variable (den Arbeitsspeicher) gespeichert werden soll. Hier wird nicht direkt eine Variable angelegt, sondern der String direkt an die Funktion übergeben.

    AutoIt
    _SQLite_Exec($DB, "INSERT INTO Tabelle (Name, Vorname, Summe) Values ($Vorname, $Name, $Telefon)")
    ; und
    local $sInsertStatement = "INSERT INTO Tabelle (Name, Vorname, Summe) Values ($Vorname, $Name, $Telefon)"
    _SQLite_Exec($DB, $sInsertStatement)

    ist also (fast) das gleiche. Es ist ja auch sinnvoll, denn wenn du in einem String z.B. den Text $Vorname verwenden willst, geht das nicht mehr. Deshalb musst du im Code sagen, dass du an der Stelle nicht den Text "$Vorname", sondern die Variable verwenden willst.

    In AutoIt wird das meistens gemacht, indem mehrere Strings genommen und zusammengefügt werden:

    AutoIt
    _SQLite_Exec($DB, "INSERT INTO Tabelle (Name, Vorname, Summe) Values (" & $Vorname & ", " & $Name & ", " & $Telefon & ")")

    Hier wird der String hinter "Values (" beendet und die Variable $Vorname angehängt. Dann wird der String ", " angehängt, usw.

    & ist der Operator (wie + für addition) um Strings, bzw. Variablen hintereinander als Text zusammenzufügen.

    Eine andere Möglichkeit wäre StringFormat. Dabei ist es möglich die Variable zu formatieren. Es wird zb. mit %s ein String angegeben, der dann später durch den Inhalt der Variable ersetzt wird. Dabei können z.b. Dinge angegeben werden, wie die Länge der Variable soll mindestens 10 Zeichen sein, und wenn welche fehlen, werden Leerzeichen davor eingefügt uvm. Am besten kannst du dir dazu die Hilfe zu StringFormat durchlesen.

    AutoIt
    local $sVorname="Max", $sName="Mustermann", $sTelefon="1023734634"
    ConsoleWrite("INSERT INTO Tabelle (Name, Vorname, Summe) Values (" & $sVorname & ", " & $sName & ", " & $sTelefon & ")"&@crlf)
    ConsoleWrite(StringFormat("INSERT INTO Tabelle (Name, Vorname, Summe) Values (%s, %s, %s)", $sVorname, $sName, $sTelefon)&@crlf)
    
    local $arNames=[["Max","Mustermann"],["Test","Other"],["Names","Multiple"],["Example","Names"],["Other","Name"]]
    ConsoleWrite(StringFormat("% 10s % 10s)", "Vorname", "Nachname")&@crlf)
    for $i=0 to UBound($arNames)-1 step 1
        ConsoleWrite(StringFormat("% 10s % 10s", $arNames[$i][0], $arNames[$i][1])&@crlf)
    next

    MfG, Kanashius.

    Edit: Schaut aus als ob das einfügen von Code mit dem "Inline-Code"-Button eine schlechte Idee ist.

  • Hallo Kanahius,

    erst einmal vielen Dank für Deine Antwort! Jetzt zeigt sich aber vermutlich, wie wenig ich dann doch im Detail verstehe... Also, verstanden habe ich: Zwischen den doppelten Anführungszeichen funktionieren keine Variablen mehr, alles wird als Text gewertet.

    Dein erstes Code-Beispiel soll daran nichts verändern, oder? Wenn ich das anstatt meines Codes nutze, ist das Ergebnis das Gleiche: Eine neue Zeile in der DB mit leeren Feldern.

    Dein zweites Beispiel verstehe ich nicht so ganz. Ich hatte auch schon etwas in der Art versucht, aber es offensichtlich noch nicht durchdrungen. Also, wie ich es verstehe: ich definiere die Variable als String und füge die verkettet ein. Wenn ich den Code kopiere, bekomme ich die folgende Fehlermeldung. Die hatte ich auch schon mal und mir gedacht: OK, hier sucht er offenbar nach Spalten mit dem Namen meiner Variablen. Hm, wie Du siehst: Ich weiß nicht mal genau, wie ich jetzt die Frage formulieren soll...

    --> Function: _SQLite_Exec

    --> Query: INSERT INTO Tabelle (Name, Vorname, Summe) Values (Holger, Esseling, 99874)

    --> Error: no such column: Holger

    Dein drittes Code-Beispiel gibt die Dinge sehr schön formatiert in der Console aus, schreibt aber nichts in die DB. Vermutlich denkst Du jetzt: Ja, mein Lieber, Du sollst auch nicht einfach kopieren, sondern nachdenken... Aber sorry, ich verstehe es einfach nicht, wie ich meine Eingabe aus der GUI (z.B. $Vorname) in eine neue Datenbankzeile schreibe. Auf Basis Deiner Ausführungen habe ich jetzt ein paar Anläufe und Variationen ausprobiert, aber diesen entscheidenden Schritt habe ich noch nicht geschafft.

    Herzliche Grüße und vielen Dank nochmal!

    Holger

    P.S.: Wie fügt man den Code denn richtig ein? Ich hatte "Code" und nicht "Inline-Code" genommen und das sah bei mir (und für mein Verständnis) ganz anständig aus.

  • Ja, das erste Codebeispiel war nur zum zeigen und noch keine Lösung.

    Ich hab beim zweiten nicht ganz aufgepasst. Also: Es ist schon alles richtig, was ich betreffend der Strings erklärt habe, aber bei SQL statements gibt es noch eine Besonderheit.

    Auch die Datenbank muss wissen, dass du dort einen String (bzw. bei SQLite TEXT) übergibst.

    So wie du in AutoIt einen String angibst, indem du ihn mit " umschließt (nebenbei: wenn du " in einem String haben möchtest kannst du das mit verdoppelung erreichen, dementsprechend wird bei $sData="Dies ist ein ""cooler"" Text" das cooler in Anführungszeichen stehen.),

    musst du bei SQL auch zeigen, dass es ein String ist. Das geht, indem du dort ' oder ` verwendest.

    AutoIt
    _SQLite_Exec($DB, "INSERT INTO Tabelle (Name, Vorname, Summe) Values (`" & $Vorname & "`, `" & $Name & "`, `" & $Telefon & "`)")

    Vorher wusste SQLite nicht, dass das ein String sein soll und hat stattdessen nach der Spalte mit dem Namen Holger gesucht, anstatt den String `Holger` in die Tabelle einzufügen. => no such column: Holger

    Die Query muss also so aussehen: INSERT INTO Tabelle (Name, Vorname, Summe) Values (`Holger`, `Esseling`, `99874`)

    P.S.: Mit Code ist es schon richtig, das hab ich auch verwendet. Wwenn du den Quellcode nach dem einfügen nochmal anklickst kannst du oben als Syntax-Hervorhebung AutoIt auswählen, dann wird der Code auch farbig hervorgehoben.

  • Hab mal eine Schaufel geholt und einen gaaanz alten Beitrag von mir ausgegraben :rofl:

    BugFix
    1. Mai 2008 um 16:55

    Könnte auch hilfreich sein.

  • Hallo BugFix,

    super, vielen Dank! Das sieht in der Tat sehr hilfreich aus, wobei es mir im ersten Schritt sehr lieb ist, die Dinge einmal (für mich) verständlich zu schreiben, bis sie funktionieren. Danach scheint mir Dein Werkzeug eine große Erleichterung zu sein.

    Herzliche Grüße

    Holger

  • wobei es mir im ersten Schritt sehr lieb ist, die Dinge einmal (für mich) verständlich zu schreiben, bis sie funktionieren.

    Das ist eine vernünftige Einstellung. SQLite verfügt über eine extrem umfangreiche Dokumentation, die in einigen Teilen für den reinen AutoIt-Anwender sicher schwierig zu lesen ist, da diese Umsetzung (sofern in der SQLite.au3 erfolgt) innerhalb der UDF stattfindet.

    Jedoch muss man ja auch nicht das Rad neu erfinden. Man kann auch sehr gut verstehen, wenn man sich die UDF vornimmt und versucht nachzubilden, was dort passiert.

    Wir haben aber auch ein Unterforum Datenbanken - dort findest du sicher auch einige Anregungen.