[VB6+.mdb] entries niet in juiste volgorde

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • klein is fijn
  • Registratie: Mei 2005
  • Laatst online: 07-01-2022
Sinds ik bezig ben met een .mdb database aan VB6 te hangen heb ik problemen met de volgorde waarin de data in de database gezet wordt.
Ik stuur de volgende code aan via een timer van 10 seconden. Deze kijkt of een database met de naam van die dag nog niet bestaat, waarna die aangemaakt wordt indien nodig, om er vervolgens een entry in te zetten. Deze entries bestaan uit een een datum + tijd in de eerste kolom, en vervolgens 18 keer een setpoint + temperatuur.

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Private Function SaveInDatabase()
  On Error GoTo DatabaseWriteError
  Dim FileSystem As FileSystemObject
  Set FileSystem = New FileSystemObject
  
  Dim db As Database, FileName As String, n As Byte, rstRecordset As Recordset
  
  FileName = ResultFolderStr & "\" & Format(Now, "yymmdd") & ".mdb" ' create filename
  If (Not FileSystem.FileExists(FileName)) Then   ' if database doesn't exists
    On Error GoTo DatabaseCreateError
    
    Set db = DBEngine(0).CreateDatabase(FileName, dbLangGeneral, dbVersion30) ' create the database
    Dim TblDef As TableDef
    
    Set TblDef = db.CreateTableDef("Data") 'create table
    TblDef.Fields.Append TblDef.CreateField("time", dbText, 22)
    For n = 1 To 18
      TblDef.Fields.Append TblDef.CreateField("adr" & CStr(n) & "_sp", dbSingle) ' setpoints
      TblDef.Fields.Append TblDef.CreateField("adr" & CStr(n), dbSingle) ' temperatures
    Next
    db.TableDefs.Append TblDef ' append to database
    
  End If
  
  Set db = DBEngine.Workspaces(0).OpenDatabase(FileName)
  
  Set rstRecordset = db.OpenRecordset("SELECT * FROM Data", dbOpenDynaset)
  rstRecordset.AddNew
  rstRecordset.Fields("time") = Format(Now, "dd-mm-yyyy hh:mm:ss") ' date + time
  For n = 1 To 18
    rstRecordset.Fields("adr" & CStr(n) & "_sp") = Round(Setpoint(n), 1) ' setpoint
    If (Temperature(n) > -10000) Then ' < -10000 = no data
      rstRecordset.Fields("adr" & CStr(n)) = Round(Temperature(n), 1) ' temperature
    Else
      rstRecordset.Fields("adr" & CStr(n)) = Null
    End If
  Next
  rstRecordset.Update ' update to database
  
  Exit Function
  
  
DatabaseWriteError:
  Call SaveLogEvent(TLdatabase, 0, TLwriteerror, TLnotemp, "", "Could not write to database, results not saved - error in " & Err.Source & " - " & Err.Description & " (" & Err.Number & ")")
  Exit Function
  
DatabaseCreateError:
  Call SaveLogEvent(TLdatabase, 0, TLwriteerror, TLnotemp, "", "Could not create database, results not saved - error in " & Err.Source & " - " & Err.Description & " (" & Err.Number & ")")
  
End Function


Dat levert de volgende database op:
Afbeeldingslocatie: http://www.kleinisfijn.nl/co/uploads/thumbs/database_01.png klikbaar
De kolommen van de temperaturen zijn nog even leeg, omdat de juiste hardware nog niet aan de computer hangt, dus zet ie null erin. Geen probleem daar.
Wel een probleem in de volgorde van de tijden. Van boven naar beneden eerst 00:01:50 t/m 00:05:20, vervolgens 00:00:00 t/m 00:01:40 en dan weer verder met 00:05:30. Daarna doet ie alles in de juiste volgorde tot middernacht.

Errug vaag, dus ik ben even aan het spelen gegaan met de volgende resultaten:
  • De fout is reproduceerbaar op meerdere computers op alle mogelijke tijden door de windows klok aan te passen naar middernacht.
  • Het maakt niet uit of ik het VB project run, of de uiteindelijke .exe.
  • Ik kan de fout beinvloeden door de namen van de kolommen te veranderen. Ik zat eerst op 9 minuten verkeerd met de kolomnamen block_01_sp en dergelijke, dat heb ik teruggekregen naar ongeveer 5 minuten met de huidige kolomnamen.
  • Het is geen timing probleem. Ik heb handmatig een sloot kopieen van de database file gemaakt op het moment dat de eerste 50 entries erin werden gezet, en ik zie dat 00:00:00 er als eerste in wordt gezet. Alle entries tot 00:01:40 worden netjes eronder gezet. De entry van 00:01:50 wordt opeens bovenaan gezet, met alles t/m 00:05:20 daaronder. Vanaf 00:05:30 worden alle entries weer helemaal onderaan toegevoegd.
Na een ruim weekje zoeken werd ik het wel eens zat, vandaar dat ik nu de boel hier neerzet.
Ik wil afsluiten met twee vragen: Wat gebeurt hier en hoe los ik het op?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
De volgorde van records in een tabel is niet gegarandeerd (en al helemaal niet als je geen index or pimary key (wat vaak ook een index is) gebruikt). Er is helemaal geen probleem; de weergave van Access is gewoon just-that. Zet een order by in een query en je probleem is opgelost.

Waarom zou je overigens elke dag een nieuwe DB maken? Je kunt toch heel die zooi van een jaar (en jaaaaren) gewoon in 1 DB mikkeren? Als je de gegevens van dag X wil hebben doe je gewoon een where [time]=foo et voila. Als je nu gegevens over een heel jaar wil gaan gebruiken moet je 365 mdb's openen :X

Zet dan meteen een index op je 'time' veld; daarmee zal het uitvoeren van de where-clause aanzienlijk sneller gaan (en dat wil je) en zal, als neveneffect, waarschijnlijk je weergave ook meteen goed zijn (maar dan nog wil je een order by gebruiken, je wil nooit vertrouwen op een impliciete volgorde; feitelijk levert de DB je de records aan in de volgorde zoals 't 'm 't best uit komt, tenzij je dus expliciet een sortering vraagt).

[ Voor 43% gewijzigd door RobIII op 22-02-2010 20:56 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17:02
Lang niet gezien ook, DAO. Overweeg om ADO te pakken voor nieuwe projecten.

[ Voor 4% gewijzigd door farlane op 22-02-2010 21:16 . Reden: zin niet ]

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Time kan trouwens veel beter als type date hebben dan text. Daarnaast is "dd-mm-yyyy" niet handig bij niet-Nederlandstalige systemen (en mocht je het op tekst houden, dan sorteer je ook nog eens verkeerd als je meer dan 1 dag hebt).

Daarnaast zijn getallen als veldnamen soms een indicatie van een verkeerd ontwerp. Of dat hier zo is, kan ik niet direct beoordelen. Stel dat je in alle adr-kolommen op 1 bepaalde waarde wilt zoeken, dan is dit een onhandig ontwerp.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
pedorus schreef op maandag 22 februari 2010 @ 21:12:
Time kan trouwens veel beter als type date hebben dan text.
:D Dat was me nog niet eens opgevallen :P

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • klein is fijn
  • Registratie: Mei 2005
  • Laatst online: 07-01-2022
RobIII schreef op maandag 22 februari 2010 @ 20:52:
De volgorde van records in een tabel is niet gegarandeerd (en al helemaal niet als je geen index or pimary key (wat vaak ook een index is) gebruikt). Er is helemaal geen probleem; de weergave van Access is gewoon just-that. Zet een order by in een query en je probleem is opgelost.
Dat was makkelijk, en het werkt prima.
Waarom zou je overigens elke dag een nieuwe DB maken? Je kunt toch heel die zooi van een jaar (en jaaaaren) gewoon in 1 DB mikkeren? Als je de gegevens van dag X wil hebben doe je gewoon een where [time]=foo et voila. Als je nu gegevens over een heel jaar wil gaan gebruiken moet je 365 mdb's openen :X
Dat is misschien nog eens een leuke uitbreiding voor later, al worden de files wel vrij lomp. Ik zit nu aan een ruime 2MB per database. Voor een heel jaar zou dat dan een krappe 1GB worden. Data van een heel jaar openen hoeft niet in mijn toepassing, het is belangrijker om het makkelijk per dag te kunnen bekijken. Zoeken in de database gebeurt ook niet. De hele database wordt puur en alleen gebruikt als opslag

De ADO en date type ga ik ook op het todo lijstje zetten, al denk ik niet dat daar snel naar gekeken wordt zolang dit werkt.

Dank voor de tips & oplossingen.
Pagina: 1