Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Delete records in a random file
#1
The example is a random file that is connected to an index file. A kind of ISAM file management. The practical sense should be:
One cannot simply delete a record from a random file; For example, the data record with the item number (key) 2345 should be deleted.

To make this possible, entry 2345 in the index file must first be deleted, but the data record number, which is also saved and refers to the random file, remains intact. By deleting entry 2345 in the index file, all occupied entries in the index file move down, while the "deleted" entry with the data record number is stored as the first free field above it. The effect is that if a new data record is written, then the "deleted" data record is overwritten. In this respect, a random data record has been deleted after all. - So much for the theory.

The template for the example is from a book. There is no error message, but the result is not convincing!  Sad  I can't figure out why nothing useful is displayed. But there must be a logical error somewhere.

Maybe someone could look at the whole thing and find the error. Thanks!

Create random file:
Code: (Select All)

'Randomdatei mit Index, Hueckstaedt S. 321 - 13. Mai 2024

$Console:Only

Option _Explicit

Type Warenposten
  nummer As String * 4
  artikel As String * 10
  preis As Double
End Type

'Variable von Warenposten
Dim datensatz As Warenposten

Declare Sub AddiereSchluessel(i As Integer, nummer As String, index() As String)

Dim As Integer maxAnzahl, i, k

'Indexdatei fuer maximal 20 Datensaetze anlegen
maxAnzahl = 10
Dim As String index(maxAnzahl)
For i = 1 To maxAnzahl
  index(i) = "9999":
Next i

'Randomdatei anlegen bzw. oeffnen.
'Len muss dem laengsten Datensatz entsprechen
Open "RandomIndex.dat" For Random As #5 Len = Len(datensatz)

i = 1
Do
  'Daten aus Datazeile einlesen
  Read datensatz.nummer
  Read datensatz.artikel
  Read datensatz.preis

  'Datensatz in Datei schreiben
  Put #5, i, datensatz

  'Index aktuallisiren
  Call AddiereSchluessel(i, datensatz.nummer, index())

  'Zeiger erhoehen
  i = i + 1

Loop Until datensatz.nummer = "9999"

'Datenbank schliesen
Close #5

'Indexdatei schreiben
Open "RandomIndex.ind" For Output As #3
For k = 1 To maxAnzahl
  Print #3, index(k)
Next k

Close #3
End
:

Data 1233,Lenker,245.99
Data 0891,Lampe,188.90
Data 1122,Telegabel,499.95
Data 2301,Tank,377.50
Data 1755,Sitzbank,321.00
Data 9999,"",0

Sub AddiereSchluessel (i As Integer, nummer As String, index() As String)

  Dim As String zahl, einfuegen
  Dim As Integer k

  zahl = " ": RSet zahl = Str$(i)

  k = 1: einfuegen = nummer + zahl

  Do While einfuegen > index(k) And k <= i
    k = k + 1
  Loop

  Do While k <= i
    Swap einfuegen, index(k)
    k = k + 1
  Loop

  index(k) = einfuegen
End Sub

Output of the data
Code: (Select All)

'Die erstellte Randomsatei mit Index lesen - Hueck S.324 - 26. Mai 2024

Cls

Option _Explicit

Type Warenposten
  nummer As String * 4
  artikel As String * 10
  preis As Double
End Type

'Variable von Warenposten
Dim datensatz As Warenposten

Dim As Integer maxAnzahl, i, k, z

'Indexdatei einlesen
maxAnzahl = 10
Dim As String index(maxAnzahl)

i = 0
Open "RandomIndex.ind" For Input As #3
Do While Not EOF(3) And index(i) <> "9999"
  i = i + 1
  Input #3, index(i)
Loop
Close #3

k = i - 1

'Randomdatei oeffnen
Open "RandomIndex.dat" For Random As #5 Len = Len(datensatz)
Print "Nr.    Artikel              Preis"
Print

i = 1
Do While Not i > k
  z = Val(Right$(index(i), 4))

  'Datensatz lesen
  Get #5, z, datensatz

  'Dateiende Kennzeichnung
  If datensatz.nummer = "9999" Then Exit Do

  'Datensatz ausgeben
  Print Using "\  \"; datensatz.nummer;
  Print "    ";
  Print Using "\              \"; datensatz.artikel;
  Print "    ";
  Print Using "####.##"; datensatz.preis

  'Zeiger erhoehen
  i = i + 1
Loop

Close #5

End 'Hauptprogramm

[Image: Random-Index-Datei-ausgeben2024-05-26.jpg]
Reply
#2
Let me give you the world's most hidden secret in how to delete files from a database:

Code: (Select All)
Type Warenposten
  invalid As _BYTE
  nummer As String * 4
  artikel As String * 10
  preis As Double
End Type

Now, compare that to what you have in your own code above. See the extra entry?

With a flip of that single byte in each record, you can flag a record as being "deleted" or "invalid".... And, most amazingly, since the record is still there -- just flagged "invalid" -- you can now also add an option to "undelete" and validate that record once again!

Yo just built a RECYCLE BIN into your database! That's all it takes to expand that random record that much!



Now, if you want to PACK the database, or PURGE deleted files, all you do is basically write a short routine to run the length of the database:

FOR i = 1 TO Record_Length
GET #1,i, record
IF record(i).invalid THEN
'skip record
ELSE
PUT #2, ,record
END IF
NEXT

Copy all the records from the old database over to a new database, as long as that "invalid" flag hasn't been set for them.

It's much more efficient than trying to rebuild/reindex the database with every "delete", and you have the option of scheduling it for times when the user isn't using the database for anything else. (Like a 2AM repacking time every Sunday night...)
Reply
#3
Quote:Copy all the records from the old database over to a new database, as long as that "invalid" flag hasn't been set for them.
I know this is the standard method that is found in every relevant manual. The procedure I described is something I have never read in any other instructions. I'll have to look at the suggestions again. Thanks for that.

The main reason for my request for help has probably been lost somehow, because my current problem is that both programs work together without displaying an error, but the result is wrong. Why is that? It have to a logical misteke.

Until I can not fix this error, I can not try indexing.
Reply




Users browsing this thread: 3 Guest(s)