Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Hilfe zu SQLite, Aufbau, Abfrage, Ändern etc.


  • Please log in to reply
84 replies to this topic
fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Hallo!

 

Ich kram den Thrad mal wieder hervor da es im Thema weitergeht :)

 

Ich bin gerade dabei einen Offline Modus in den Reminder zu integrieren. Dazu will im im Fall das der Nertzwerkpfad nicht erreichbar ist den Inhalt des 1. ListViews in eine Lokale DB schreiben und diese dann weiterverwenden.

 

Einzeln die Reihen auslesen und per DB.Exec in die DB schreiben bekomm ich hin. Ich frag mich aber ob sowas nicht einfacher geht.

Wenn ich das richtig verstehe, brauche ich ein Object mit den Daten aus dem Listview um dieses dann mit einem DB.Exec Durchgang in die DB zu schreiben, korrekt?

Könnt ihr mir Verraten wie man ein solches Object erstellt?

Aus der Hilfe versteh ich es nicht so wirklich.

 

MfG
fump



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Hallo,

 

SQLiteDB akzeptiert keine Objekte als Parameter für DB.Exec(). Du kannst aber die einzelnen INSERT-Anweisungen getrennt durch ";" in einem String verkettet übergeben. Wenn Du das dann noch in eine Transaktionsklammer packst, ist das ziemlich schnell.

 

MfG

 

just me


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Was meinst du mit Transaktionsklammer?



just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Oh Mann,

 

schau mal in Dein Skript. Welche Anweisungen scheinen Dir am besten zum deutschen Wort Transaktion zu passen? Und was macht eine Klammer? (Tipp: Normalerweise umschließt sie Etwas.)

 

MfG

 

just me wink.png


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

ähm... ja... klar...

 

DB.Exec() führt die Transaktionen aus.

 

Normalerweise bau ich doch den Befehl auf indem ich dies hier erstelle:

SQL := "INSERT INTO " . TableName . " VALUES('" . RM_ID . "', '" . RM_KDNr . "', '" . RM_DID . "', '" . RM_ToDo_DropDown . "', '" . RM_RRNr . "', '" . RM_DateTime . "', 'Offen', '" . RM_ToDo_Text . "', '" . RM_ToDo_Erl_Text . "', '" . UserName . "', '" . FullTime . "', '1', '');"

Du meintest nun ich soll mehrere Anweisungen hinterneinader legen und durch ; trennen. Ein ; schließt ja ohnehin eine Anweisung ab. Wenn ich also per Loop die Daten hole dann wäre der Aufbau in etwa so:

FillOffDB:
Gui, ListView, %h_LV1%
Loop % LV_GetCount()
	{
		ReihenNr:=A_Index
		Loop % LV_GetCount("Col")
			{
				LV_GetText(RM_DATA_%A_Index%, ReihenNr, A_Index)
			}
                SQLDATA := "INSERT INTO " . TableName . " VALUES('" . RM_DATA_1 . "', '" . RM_DATA_2 . "', '" . RM_DATA_3 . "', '" . RM_DATA_4 . "', '" . RM_DATA_5 . "', '" . RM_DATA_6 . "', '" . RM_DATA_7 . "', '" . RM_DATA_8 . "', '" . RM_DATA_9 . "', '" . RM_DATA_10 . "', '" . RM_DATA_11 . "', '" . RM_DATA_12 . "', '" . RM_DATA_13 . "');"
		SQL:=SQL . SQLDATA
	}
Return

Am Ende wird per DB.Exec(SQL) die Ausführung der Anweisungen gestartet.

 

Ist das richtig so?

 

Versteh dann trotzdem nicht was du mit den Klammern meinst... Soll ich noch zusätzliche Klammern einfügen? Wenn ja wo?

 

MfG
fump



hd0202
  • Members
  • 709 posts
  • Last active: Feb 14 2016 08:05 PM
  • Joined: 13 Aug 2006

er meint:

<db>.begintransaction()
<db>.endtransaction()

Hubert



fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Ach du Schande... okay... das hat mich nun echt verwirrt aber gut ist eigentlich klar.

Danke!

 

Also sollte es so aussehen:

FillOffDB:
Gui, ListView, %h_LV1%
Loop % LV_GetCount()
	{
		ReihenNr:=A_Index
		Loop % LV_GetCount("Col")
			{
				LV_GetText(RM_DATA_%A_Index%, ReihenNr, A_Index)
			}
		SQLDATA := "INSERT INTO " . TableName . " VALUES('" . RM_DATA_1 . "', '" . RM_DATA_2 . "', '" . RM_DATA_3 . "', '" . RM_DATA_4 . "', '" . RM_DATA_5 . "', '" . RM_DATA_6 . "', '" . RM_DATA_7 . "', '" . RM_DATA_8 . "', '" . RM_DATA_9 . "', '" . RM_DATA_10 . "', '" . RM_DATA_11 . "', '" . RM_DATA_12 . "', '" . RM_DATA_13 . "');"
		SQL:=SQL . SQLDATA
	}
DB.Exec("BEGIN TRANSACTION;") ; Beginn der Übertragung
If !DB.Exec(SQL) {
   MsgBox, 16, SQLite Error, % "Msg:`t" . DB.ErrorMsg . "`nCode:`t" . DB.ErrorCode . "`n`nReminder wird nun Neugestartet.
   Reload()
}
DB.Exec("COMMIT TRANSACTION;") ; Schließen der Übertragung
Return


just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Wenn Du Deinen Rechner etwas entlasten willst, dann lieber so:

Gui, ListView, %h_LV1%
SQL := ""
Loop % LV_GetCount()
    {
        ReihenNr:=A_Index
        Loop % LV_GetCount("Col")
            {
                LV_GetText(RM_DATA_%A_Index%, ReihenNr, A_Index)
            }
        SQL .= "INSERT INTO " . TableName . " VALUES('" . RM_DATA_1 . "', '" . RM_DATA_2 . "', '" . RM_DATA_3 . "', '" . RM_DATA_4 . "', '" . RM_DATA_5 . "', '" . RM_DATA_6 . "', '" . RM_DATA_7 . "', '" . RM_DATA_8 . "', '" . RM_DATA_9 . "', '" . RM_DATA_10 . "', '" . RM_DATA_11 . "', '" . RM_DATA_12 . "', '" . RM_DATA_13 . "');"
    }

 

 

Du hast Alles was Du brauchst, um zu Probieren, ob das so klappt; tue es einfach.

 

MfG

 

just me wink.png


Prefer ahkscript.org for the time being.


fump2000
  • Members
  • 591 posts
  • Last active: Nov 11 2015 07:52 AM
  • Joined: 01 Nov 2012

Mach ich ja... ich frag halt lieber einmal mehr als zu wenig.

 

Noch eine Frage weil ich dazu in der SQL Doku nichts konkretes gefunden habe. Ist INSERT OR REPLACE mit ROLLBACK verbindbar? Also ich meine ob man den ROLLBACK dennoch nutzen kann falls etwas schief geht.

 

Es geht darum das wenn der Reminder wieder in den OnlineModus wechselt das die Vorgänge der Offline DB in die Online DB integriert werden. Neue werden hinzugefügt (INSERT) vorhandene ausgetauscht (REPLACE) dennoch würde ich gerne im falle eines Fehler mit ROLLBACK TRANSACTION die aktionen rückgängig machen.

 

Wenn ich das Konstruckt richtig verstanden habe werden erst mit dem COMMIT Änderungen wirksam. Zuvor sollte über das ROLLBACK jurnal ein aufheben der Änderungen möglich sein.

 

Der Code dazu sieht so aus:

MergingDB:
DBAlias := "OfflineUserDB" ; Aliasname für die Offline Datenbank
DBOfflineFilePath := A_ScriptDir . "\Reminder-" . UserName . ".sql"
If !DB.Exec("ATTACH DATABASE '" . DBOfflineFilePath . "' AS " . DBAlias . ";") { ; Offline Datenbank hinzufügen
	SQLiteError(A_ThisLabel, DB, "ATTACH")
}
DB.Exec("BEGIN IMMEDIATE TRANSACTION;")
SQL := "INSERT OR REPLACE INTO main." . TableName . " SELECT * FROM " . DBAlias . "." . TableName
If !DB.Exec(SQL) {
	SQLiteError(A_ThisLabel, DB, "INSERT")
	DB.Exec("ROLLBACK TRANSACTION;") ; Transaktion zurücksetzen (sicher ist sicher)
	DB.Exec("DETACH DATABASE " . DBAlias . ";") ; Offline Datenbank entfernen
	IniWrite,1, %A_ScriptDir%\funktionen.ini, REMINDER, OfflineModus
	Reload()
}
DB.Exec("COMMIT TRANSACTION;")   ; Alles ist fehlerfrei gelaufen, die Transaktion kann gültig gesetzt werden.
If !DB.Exec("DETACH DATABASE " . DBAlias . ";") {  ; Offline Datenbank entfernen
	SQLiteError(A_ThisLabel, DB, "DETACH")
}
Filedelete, %DBOfflineFilePath% ; Offline Datenbank löschen
Return


just me
  • Members
  • 1496 posts
  • Last active: Nov 03 2015 04:32 PM
  • Joined: 28 May 2011

Das sollte genau so laufen, wie Du es Dir gedacht hast. Die Chance, dass by "INSERT OR REPLACE" ein Fehler Auftritt, ist allerdings recht gering. Wenn überhaupt, werden es relativ harte Brocken, wie z.B. Speicherplatzmangel oder ein Verbindungsverlust sein. Bei einem Verbindungsverlust können weitere Anweisungen für die DB nicht ausgeführt werden. Wenn die Macher von SQLite die Transaktionssteuerung ordentlich implementiert haben, sollten die bis dahin gelaufenen Veränderungen der DB trotzdem nicht wirksam werden.


Prefer ahkscript.org for the time being.