So ich stelle mal mein erstes Testprogramm hier ein, zunächst hat Pablo einige Methoden um O (Original = UTF8)
und A (ANSI) erweitert, das gibt für uns aber Probleme bei OEM EXE Dateien - das will ich anders machen, aber zunächst eine Anpassung für OEM EXE und ANSI Protokoll :
(Pablo hat auch eine Methode die die Rückgabewerte gleich ins Zieldatenformat umwandelt.)
Code: Alles auswählen
#include "ot4xb.ch"
//----------------------------------------------------------------------------------------------------------------------
proc main()
local db, n, i, nStart, nRecNr
local stm,aa, nAnzTestRec := 100
set charset to OEM // äöü - wegen Anzeige in CMD Box
delete file test.db // hier immer UTF8 !
set alternate to test.txt
set alternate on
cls
?
? "Existiert test.db noch, trotz Löschung: ",file("test.db")
?
nRecNr := 0
db := TSqLiteDb():Open("test.db")
aa := db:exec("SELECT sqlite_version()")
if ! empty(aa) // NIL w„re m”glich
? "sqlite_version(): ",aa[1,1] , valtype(aa[1,1])
else
? "sqlite_version(): ",aa
endif
?
if ! db:lIsTable("t")
db:exec( "CREATE TABLE t (id integer PRIMARY KEY AUTOINCREMENT UNIQUE, name, vorname, strasse, plz, ort )" ) // keine Umlaute in Feldnamen (zumindest bei mir)
end
? time(),"Erzeuge",nAnzTestRec,"S„tze ohne begin transaction"
nStart := seconds()
for n := 1 to nAnzTestRec
@ row(),50 say n
nRecNr++
stm := db:exec_begin("INSERT INTO t(name, vorname, strasse, plz, ort) VALUES (:name, :vorname, :strasse, :plz, :ort)")
db:bind_textA(stm ,":name", convToAnsiCP("Name ÄÖÜ "+str(nRecNr,5)))
db:bind_textA(stm ,":vorname",convToAnsiCP("Vorname äöü "+str(nRecNr,5)))
db:bind_textA(stm ,":strasse",convToAnsiCP("Straße "+str(nRecNr,5)))
db:bind_textA(stm ,":plz", strZero(n,5))
db:bind_textA(stm ,":ort", "Ort /\[|]{}"+str(nRecNr,5))
db:exec_end(stm)
next
? "Dauer: ",seconds()-nStart
?
? "Erzeuge",nAnzTestRec,"Sätze MIT begin transaction" // Hinweis aus Basic4Android Forum
nStart := seconds()
stm := db:exec_begin("BEGIN TRANSACTION")
db:exec_end(stm)
for n := 1 to nAnzTestRec
@ row(),50 say n
nRecNr++
stm := db:exec_begin("INSERT INTO t(name, vorname, strasse, plz, ort) VALUES (:name, :vorname, :strasse, :plz, :ort)")
db:bind_textA(stm ,":name", convToAnsiCP("Name ÄÖÜ "+str(nRecNr,5)))
db:bind_textA(stm ,":vorname",convToAnsiCP("Vorname äöü "+str(nRecNr,5)))
db:bind_textA(stm ,":strasse",convToAnsiCP("Straße "+str(nRecNr,5)))
db:bind_textA(stm ,":plz", strZero(n,5))
db:bind_textA(stm ,":ort", "Ort /\[|]{}"+str(nRecNr,5))
db:exec_end(stm)
next
stm := db:exec_begin("END TRANSACTION")
db:exec_end(stm)
? "Dauer: ",seconds()-nStart
?
nStart := seconds()
? "Erzeuge 10000 Sätze mit begin transaction"
stm := db:exec_begin("BEGIN TRANSACTION")
db:exec_end(stm)
for n := 1 to 10000
@ row(),50 say n
nRecNr++
stm := db:exec_begin("INSERT INTO t(name, vorname, strasse, plz, ort) VALUES (:name, :vorname, :strasse, :plz, :ort)")
db:bind_textA(stm ,":name", "Name "+str(nRecNr,5))
db:bind_textA(stm ,":vorname","Vorname "+str(nRecNr,5))
db:bind_textA(stm ,":strasse","Strasse "+str(nRecNr,5))
db:bind_textA(stm ,":plz", strZero(n,5))
db:bind_textA(stm ,":ort", "Ort "+str(nRecNr,5))
db:exec_end(stm)
next
stm := db:exec_begin("END TRANSACTION")
db:exec_end(stm)
? "Dauer: ",seconds()-nStart
? time(),"Suche alle die '55' im Namen haben ... "
nStart := seconds()
stm := db:exec_begin("SELECT id,name, vorname, strasse, plz, ort FROM t WHERE name like '%55%' ORDER BY ID")
// aa := db:exec_end_ex(stm,,,"IICI" )
aa := db:exec_end(stm)
? time(), "Treffer: ",len(aa)," Dauer: ",seconds()-nStart
wait
? "lfdNr. ID ,Name ,Vorname ,Strasse ,Plz ,Ort"
for n := 1 to len(aa)
? str(n,5)+":",str(val(aa[n,1]),6)
for i := 2 to len(aa[n])
?? ",",cUtf8ToOem(aa[n,i]) // Texte sind noch in UTF8 !
next
next
? "Zeige die Tabellen in der Datei:"
aEval( db:aTableNames() , {|a,i| qout(str(i,3)+".",a)} )
?
set alternate to
memowrit("test.txt",convtoAnsiCP(memoread("test.txt")))
db:Close()
inkey(10)
return
und das Ergebnis:
Code: Alles auswählen
Existiert test.db noch, trotz Löschung: N
sqlite_version(): 3.7.14.1 C
10:53:40 Erzeuge 100 Sätze ohne begin transaction
Dauer: 10,94
Erzeuge 100 Sätze MIT begin transaction
Dauer: 0,15
Erzeuge 10000 Sätze mit begin transaction
Dauer: 2,00
10:53:53 Suche alle die '55' im Namen haben ...
10:53:53 Treffer: 282 Dauer: 0,03
Press any key to continue...
lfdNr. ID ,Name ,Vorname ,Strasse ,Plz ,Ort
1: 55, Name ÄÖÜ 55, Vorname äöü 55, Straße 55, 00055, Ort /\[|]{} 55
2: 155, Name ÄÖÜ 155, Vorname äöü 155, Straße 155, 00055, Ort /\[|]{} 155
3: 255, Name 255, Vorname 255, Strasse 255, 00055, Ort 255
4: 355, Name 355, Vorname 355, Strasse 355, 00155, Ort 355
5: 455, Name 455, Vorname 455, Strasse 455, 00255, Ort 455
6: 550, Name 550, Vorname 550, Strasse 550, 00350, Ort 550
7: 551, Name 551, Vorname 551, Strasse 551, 00351, Ort 551
8: 552, Name 552, Vorname 552, Strasse 552, 00352, Ort 552
9: 553, Name 553, Vorname 553, Strasse 553, 00353, Ort 553
10: 554, Name 554, Vorname 554, Strasse 554, 00354, Ort 554
...
270: 9553, Name 9553, Vorname 9553, Strasse 9553, 09353, Ort 9553
271: 9554, Name 9554, Vorname 9554, Strasse 9554, 09354, Ort 9554
272: 9555, Name 9555, Vorname 9555, Strasse 9555, 09355, Ort 9555
273: 9556, Name 9556, Vorname 9556, Strasse 9556, 09356, Ort 9556
274: 9557, Name 9557, Vorname 9557, Strasse 9557, 09357, Ort 9557
275: 9558, Name 9558, Vorname 9558, Strasse 9558, 09358, Ort 9558
276: 9559, Name 9559, Vorname 9559, Strasse 9559, 09359, Ort 9559
277: 9655, Name 9655, Vorname 9655, Strasse 9655, 09455, Ort 9655
278: 9755, Name 9755, Vorname 9755, Strasse 9755, 09555, Ort 9755
279: 9855, Name 9855, Vorname 9855, Strasse 9855, 09655, Ort 9855
280: 9955, Name 9955, Vorname 9955, Strasse 9955, 09755, Ort 9955
281: 10055, Name 10055, Vorname 10055, Strasse 10055, 09855, Ort 10055
282: 10155, Name 10155, Vorname 10155, Strasse 10155, 09955, Ort 10155
Zeige die Tabellen in der Datei:
1. sqlite_sequence
2. t
FAZIT:
JEDE einzelne Schreiboperation wird als Transaktion behandelt, solange man nicht selbst eine Transaktion einleitet.
Davon können wir unter DBF nur träumen !
Schnell ist es auch, wobei die Daten hir lokal liegen und noch kein konkurierender Zugriff stattgefunden hat, aber immerhin.
UND man könnte die SQLite Tabelle auch im RAM halten wenn man wollte.
PS: wer einen SQLite Dateimanager braucht, ich nehme diesen hier - ich finde ihn gut :
http://sqlitebrowser.sourceforge.net/
http://sourceforge.net/projects/sqlitebrowser/