Memos reorg

Konzeptionelles, Technisches, Termine, Fragen zum Hersteller usw.

Moderator: Moderatoren

Antworten
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Memos reorg

Beitrag von Rudolf »

Hallo,
habe bei einem Kunden ein Problem mit einer viel zu großen Memodatei, ist entstanden nachdem die Festplatte voll war und das Programm abgestürzt ist. Danach wurde die Festplatte wesentlich erweitert und das Programm hat normal wieder funktioniert. Jedoch ist eine Memodatei riesengroß geworden. Habe versucht den Inhalt unwichtiger Memofelder zu löschen, aber die Datei wird nicht kleiner. Habe danach auch reorganisiert, hat nichts genutzt. Muss ich die Daten noch zuerst in eine andere Datei mit copy to kopieren und dann wieder importieren dass die Memos reorganisiert werden ?
Mache gerade eine Testfunktion welche die Größe der einzelnen Memofelder prüft um zu sehen ob vielleicht ein Memofeld viel zu groß ist.
Grüße
Rudolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

PACK wirkt nicht auf MEMO Dateien.
Einfach COPY TO ... dann das Original löschen und die Kopie umbenennen.
Das ist sicher (weil das Original bestehen bleibt bis die Kopie erstellt wurde) und so schnell wie möglich (weil nur einmal kopiert werden muss).
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von Tom »

Sehr wahrscheinlich liegt ein physischer/physikalischer Schaden vor. Irgendein Offset ist im Eimer, die Datei sprengt alle Grenzen. Es gibt Fehler beim Lesen. COPY TO oder DbExport() schmieren ebenfalls ab. Wenn man keine brauchbare Datensicherung hat, besteht meiner Erfahrung nach der einzige Weg darin, die Originaltabelle feldweise umzukopieren, wobei alle FieldGet()- und FieldPut()-Vorgänge in Sequenzen eingebettet werden müssen, um Lesefehler in einzelnen Datensätzen umgehen zu können. Der Anteil sinnvoll restaurierter Daten kann in dieser Situation sehr hoch ausfallen, muss es aber - leider - nicht.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

genau, meine Beschreibung bezieht sich auf eine bis dahin intakte DBF Memodatei Kombination.
Nach so einem Crash muss man die Datei leer neu erzeugen und Satz für Satz - Feld für Feld füllen.
Dabei muss man entweder nach einem Absturz im Feld DANACH weitermachen oder einen fehlerhaften Zugriff auf ein (Memo-)Feld lokal abfangen und mit dem nächsten Feld weitermachen.

Das hatten wir schon einmal ...

:arrow: http://www.xbaseforum.de/viewtopic.php? ... mo*+defekt
:arrow: http://www.xbaseforum.de/viewtopic.php? ... mo*+defekt

aber ich konnte kein fertiges Reparaturprogramm finden ...
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von Tom »

Code: Alles auswählen

PROCEDURE DateiInstandsetzen(cNewName)
* kopiert eine Datei sicher um, zu reparierende Tabelle ist geöffnet und selektiert, "cNewName" ist der Zielname für die reparierte Tabelle
local cOldName := DbInfo(DBO_FILENAME), aStruct := DbStruct(), cAlias := Alias(), nFCount := FCount(), bError, nRecNo
DbGoTop()
DbCreate(cNewName,aStruct)
USE (cNewName) ALIAS neu EXCLUSIVE NEW
DbSelectArea(cAlias)
bError := ErrorBlock({|e|Break(e)})
nRecNo := 0
DO WHILE !Eof()
  IF RecNo() = nRecNo
    DbSkip(1)
  ENDIF
  nRecNo := RecNo()
  BEGIN SEQUENCE // Laufzeitfehler werden ignoriert
  DbSelectArea('neu')
  APPEND BLANK
  FOR i := 1 TO nFCount
    x := (cAlias)->(FieldGet(i))
    FieldPut(i,x)
  NEXT
  RECOVER USING oError
    i ++
    DbSelectArea(cAlias)
    DbSkip(1)
    LOOP
  END SEQUENCE
  DbSelectArea(cAlias)
  DbSkip(1)
ENDDO

ErrorBlock(bError)
DbSelectArea('neu')
DbSelectArea(cAlias)
DbGoTop()
RETURN
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von Tom »

In der Fehlerbehandlung könnte man sich auch noch anzeigen lassen, bei welchem Datensatz/Feld Probleme auftraten.
Herzlich,
Tom
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Memos reorg

Beitrag von Rudolf »

Hallo Tom,
danke das hilft sehr, vor allem weil das System steht und der Kunde schon auf eine Lösung wartet. Prüfe dann auch die Plausibilität der Länge der Memofelder, das fehlerhafte muss viel größer sein als die anderen.
Grüße
Rudolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

Hallo Tom,

wenn ich das richtig lese ...

Code: Alles auswählen

  RECOVER USING oError
    i ++
    DbSelectArea(cAlias)
    DbSkip(1)
    LOOP
  END SEQUENCE
wird nach einem LESE-Fehler im Memofeld zum nächsten Satz gesprungen.
Dadurch werden aber die nachfolgende Felder (i++) gar nicht mehr übertragen ... oder übersehe ich etwas ?

In diesem Falle würde ich die ForNext Schleife doppelt laufen lassen, einmal alle NICHT Memofelder -> das ist unproblematisch
und im zweiten Durchgang nur die Memofelder, wenn es dann in einem kracht werden nur die weiteren Memofelder übersprungen.
Gruß
Hubert
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von Tom »

Hallo, Hubert.

Anders wird's, meine ich, auch nicht gehen. Wenn es auf einem Datensatz (!) einen Lesefehler gibt, lässt sich keines der Felder erheben. Man kann versuchen, die Struktur so zu sortieren, dass Memos immer als letztes gelesen werden, aber ich fürchte, dass das keinen Unterschied macht. Der Lesefehler tritt meiner Erfahrung nach grundsätzlich für den Datensatz auf, nicht für einzelne Felder. Aber - ausprobieren kann ja nicht schaden (bzw. kaum mehr Schaden anrichten als ohnehin schon).
Herzlich,
Tom
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9355
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von Tom »

Die Vorgehensweise wäre dann so: Die Struktur sortieren (Felder mit Feldtyp "M" - zweite Position - ans Ende), nicht über FieldGet(i) arbeiten, sondern FieldGet(FieldPos(aStruct[i,1])) verwenden.
Alternativ könnte man auch versuchen, ein Feld zu überspringen, das Fehler produziert, aber genau das hatte ich, wenn ich mich recht erinnere, auch ausprobiert, und es ging nicht.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

Wenn die DBF als solche defekt ist gebe ich dir Recht, dann ist das aber auch alles ziemlich fragwürdig ( :arrow: Datensicherung zurückladen ) ...
Aber nach meiner Erfahrung wird die DBF sauber erstellt, hat aber einen Offset für die DBT der dort nicht vorhanden ist.
In diesem Fall kann man alle nicht Memofelder einfach retten und teilweise die Memofeldinhalte.
Ein Memofeld das nicht gelesen werden kann (also es liest den Offset schmiert dann aber in der DBT ab) bleibt in der DBF leer und somit wird in Zukunft nicht mehr versucht auf ein Memofeld zuzugreifen.

Natürlich kann keiner die Garantie übernehmen, dass der Inhalt eines Memofeldes tatsächlich dem ursprünglichen entspricht.
Am Einfachsten ist es 2 Arrays zu führen, eines mit den normalen Feldnummern und ein zweites mit den Memofeldern.

Code: Alles auswählen

aStru := dbstruct()
NormalFeldArray := {}
MemoFeldArray := {}
for i := 1 to len(aStru)
   if aStru[i,DBS_TYPE ]="M"
      aadd(MemoFeldArray,i)
   else
      aadd(NormalFeldArray,i)   
   endif
next
nNormalFeldAnz := len(NormalFeldArray)
For i := 1 to nNormalFeldAnz
    ... fieldget(NormalFeldArray[i]) 
Bei vielen Datensätzen wird das sonst deutlich langsamer wenn er je Feld je Datensatz das richtige suchen muss ...
Zuletzt geändert von brandelh am Do, 23. Apr 2015 10:49, insgesamt 2-mal geändert.
Grund: Fehlerkorrektur
Gruß
Hubert
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

ich hatte oben einige Tippfehler im Beispiel ...
Gruß
Hubert
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Memos reorg

Beitrag von Rudolf »

Hallo,
danke an alle, hat beides funktioniert, auch copy to. Die Datei hatte vorher fast 70 GB und nachher ca. 30 MB. Anscheinend kein wirklicher Defekt in den Daten.
Grüße
Rudolf
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15695
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Memos reorg

Beitrag von brandelh »

Ja wenn ein Feld mit etwa 70 Gigabyte gelesen werden soll, da kann es schon sein dass Xbase++ die Puste ausgeht 8)
Gruß
Hubert
Benutzeravatar
Rudolf
Programmier-Gott
Programmier-Gott
Beiträge: 1418
Registriert: Mo, 02. Jan 2006 23:03
Wohnort: Salzburg/Österreich
Kontaktdaten:

Re: Memos reorg

Beitrag von Rudolf »

Hallo Hubert,
darum habe ich den Check für die max. Länge eines Feldes eingebaut, war aber nichts auffälliges dabei.
Grüße
Rudolf
Antworten