SQLitewrapped & BCB6



  • Ein Mittelweg scheint es nicht zu geben, oder?
    Wenn ich ein INSERT durchführe, dann wird dieses sofort in die Datei geschrieben.

    Ich vermisse die Option mit :memory: zu öffnen und als Datei zu speichern.

    Wichtiger gar als Datei zu öffnen und es wird rein im Speicher mit ihr gearbeitet und erst mittels close() oder einer save() Funktion in die Datei zurückgeschrieben.

    Ich vermisse dies, weil ich hier mit einem SpinButton Werte ändere und rechne und man sehr deutchlich die Festplatte rödeln hört bei jeder Aktion.



  • Warum musst du bei jeder Änderung von Spin Button speichern ?
    Das ist eine recht merkwürdige Art. Rechnen tust du nicht in der Datenbank.



  • Na dann erstell doch eine Memory Datenbank und speichere die dann beim Beenden in eine SQLLite File Datenbank

    ATTACH DATABASE



  • Danke für den Hinweis.

    sql-statement ::= 	ATTACH [DATABASE] database-filename AS database-name
    

    Für eine bestehende Datenbank muss ich wohl Variablen schaffen, die die Daten aufnehmen zum bearbeiten und erst am Ende es Programmes dann zurück in DB speichern. Sonst würde der Dateizugriff wohl zu massiv, da bestehende Datenbank (meines wissens) nicht als :memory: geht.



  • Ich habe den Wrapper mal übernommen und da er noch so wenig drin hat auch gern etwas erweitern.

    Mir persönlich fehlt zum Beispiel noch int mysql_num_rows($result) (PHP)
    Mein Versuch scheiterte allerdings kläglich.

    query = "SELECT COUNT(*) FROM IMDG WHERE col=5";
    sqlite_result result = db->exec_sql(query);
    printf("count:%d",result.size());
    

    Er gibt immer 1 aus, obwohl da sehr viele Datensätze drin sind und die Bedingung erfüllen. Was mach ich falsch? 🙂



  • Er hat doch recht: Das Ergebnis dieser Anfrage besteht aus einer Zeile und einer Spalte, darin steht eben die Anzahl, die Du mit COUNT(*) angefragt hast. Wahrscheinlich wird db->exec_sql(query) die Anzahl veränderter Zeilen bei einem DML-Statement zurückgeben. Du musst den Inhalt des ersten Feldes der ersten Zeile des Ergebnisses auslesen, wenn Du die Anzahl passender Zeilen haben willst.



  • BTW, warum willst Du eine solche Funktion überhaupt schreiben? Reicht nicht result.size()?



  • Danke, habs hinbekommen. Führe gleich mal Fragespiel fort. 😉

    Ich UPDATE und DELETE Einträge und aus MySQL weiss ich das ein "LIMIT 1" angehängt das ganze wesentlich beschleunigt. In SQLite jedoch meckert er Syntaxfehler wenn ein LIMIT vorhanden ist. Warum? In SELECT kann man es offensichtlich benutzen.

    Beispiel: sqlite3_exec("DELETE FROM datenbank WHERE feld=7 LIMIT 1")



  • http://www.sqlite.org/lang_update.html

    Frage total doof gewählt. SQLite unterstützt es nicht, frage sollte lauten warum nicht. Ist SQLite dahingehend optimiert oder sucht er einfach stur die komplette Datenbank dann ab, obwohl es nur einen einzigen Wert zum löschen gab?!

    Verschenkt man ziemlich viel Performance.



  • Ich weiß nicht was dieses LIMIT 1 bei DML soll. Entweder ich will alle Zeilen löschen, die dieses Kriterium entsprechen oder ich habe das Kriterium falsch gewählt. Was soll das "Lösche alle Kunden, die in Berlin wohnen, aber halt hör auf, wenn du einen beliebigen Berliner gefunden und gelöscht hast"? Die einzelnen Zeilen liegen in einer Tabelle nicht sortiert vor, wenn Du den Zugriff beschleunigen willst, dann prüfe, ob ein Index hilft.
    Wieso wird Geschwindigkeit von allen Anwendungsentwicklern immer so als extrem wichtig empfunden? Mehrbenutzersynchronisation und Transaktionsfähigkeit sind viel wichtigere Dinge. Wenn das System zu langsam ist, dann suche kein schnelleres sondern schau, wo in Deiner Anfrage der Fehler liegt.



  • Ich lösche immer über einen Primärschlüssel, wenn ich 1 Eintrag entfernen möchte. Trotzdem erhalte ich über das zusätzliche LIMIT 1 eine wesentlich kleinere Bearbeitungszeit in MySQL. Zumindest habe ich das vor 2-3Jahren festgestellt. Vielleicht hat sich dahingehend ja was getan in MySQL. Gleiches galt auch für ein Update über Primärschlüssel. Darum frag ich ja, ob SQLite dahingehend optimiert ist und merkt das Bedingung nur einen Primärschlüssel killen will und nicht ganze Datenbank auf die Bedingung prüft.



  • Normalerweise haben Datenbanksysteme ein Explain-Statement bei denen die optimierte interne Anfrage und deren geschätzten Kosten ausgegeben wird. In Postgres sieht das beispielsweise so aus:

    explain SELECT * FROM vwrptwa
    Sort (cost=923.90..924.31 rows=165 width=172)
    Sort Key: tblmtstamm.idmtstamm
    -> Hash Left Join (cost=141.31..917.82 rows=165 width=172)
    Hash Cond: (tblwarenausgang.wakeymt = tblmtstamm.idmtstamm)
    -> Hash Left Join (cost=111.13..885.37 rows=165 width=115)
    Hash Cond: (tblwarenausgang.wakeylo = tbllagerort.idlagerort)
    -> Nested Loop Left Join (cost=105.50..878.02 rows=165 width=99)
    -> Merge Left Join (cost=105.50..111.58 rows=165 width=83)
    ...

    Daran kann man erkennen, ob beispielsweise ein Table oder ein Index Scan erfolgt. SQLite besitzt wohl ein solches Explain-Statement, es soll lt. Doku aber anders verwendet werden. Da würde ich jetzt als erstes nachschauen.


Anmelden zum Antworten