Datenbankwartung?

Advantage Database Server

Moderator: Moderatoren

Antworten
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Datenbankwartung?

Beitrag von Magic »

Hi,

gibt es eine Möglichkeit eine „automatische“ Datenbankkorrektur / -reparatur / -wartung einer .DBF Tabelle durchzuführen.

Ich habe drei .DBF Tabellen, die korrupte Datensätze enthalten. Das habe ich jetzt festgestellt, als ich versucht habe ein Feld Numeric der Länge 3 auf die Länge 4 umzustellen. Dabei bekomme ich irgendwann den Fehler:

„Error 5070: The given data type is not valid fort he requested operation. Expected a numeric value. Restructure failed on record 95255.“


Den Datensatz kann ich dann löschen, korrigieren klappt nicht, und dann lasse ich das Ganze noch mal laufen. Bis zu nächsten korrupten Datensatz, usw.
Das ganze scheint mir aber extrem viel Handarbeit zu sein. Die Tabelle hat etwas mehr als 3,5 Mio. Datensätze. Wie viele davon kaputt sind? Keine Ahnung.
Datensätze in eine neue / andere .DBF zu exportieren scheitert auch an den korrupten Datensätzen.

Das einzige was ich noch nicht probiert habe, ist die Datensätze per Programm in eine neue .DBF Tabelle zu überführen.

Vielleicht jemand von Euch noch eine Idee.
Gruß,
Magic
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von brandelh »

Tom hatte mal ein Programm vorgestellt (ich meine mit Memofeldern), das korrekte Daten aus einer defekten DBF in eine andere umkopiert.
Dabei kann man ruhig die Satznummer protokollieren (eventuell auch den genauen Fehler).
Dafür muss man eine eigene ErrorRoutine bauen, die nicht abbricht, sondern diese Felder (oder Sätze) überspringt.
Also den Fehler abfangen und nach eigener Reaktion ignorieren, ähnlich der Zeile die normalerweise division durch 0 abfängt und einfach 0 zurückgibt.
Gruß
Hubert
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von UliTs »

Hallo Magic,

Du hast Dein Thema unter ADS geschrieben.
Meinst Du, dass der ADS regelmäßig für korrupte Daten sorgt?
Das kann ich mir kaum vorstellen...

Wie groß ist die DBF-Tabelle? Spielt vielleicht die 2GB-Grenze eine Rolle?

Sind nur einzelne Felder korrupt oder komplette Datensätze?
Ich habe mal eine Datei für Mirco retten können. Dabei bin ich mit LowLevel-Dateizugriff vorgegangen. Eventuell kann ich auch Dir helfen. Wenn ich es richtig verstehe, benötigst Du ein Programm, welches automatisch nach Aufruf korrupte Daten reparieren kann, damit man es immer wieder laufen lassen kann. Richtig?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: Datenbankwartung?

Beitrag von Magic »

UliTs hat geschrieben:Du hast Dein Thema unter ADS geschrieben.
Meinst Du, dass der ADS regelmäßig für korrupte Daten sorgt?
Nein, das schien mir einfach vom Thema her am besten hierher zu passen.
UliTs hat geschrieben:Wie groß ist die DBF-Tabelle? Spielt vielleicht die 2GB-Grenze eine Rolle?
Nein. Die Größte von den drei Tabellen ist gerade mal 1GB groß, die anderen beiden lediglich 0,5 MB.
UliTs hat geschrieben:Sind nur einzelne Felder korrupt oder komplette Datensätze?
Bin mir nicht ganz sicher. Ich meine es sind immer mehrere Felder pro Datensatz.
Leider kenne ich die Anzahl der kaputten Sätze nicht.
UliTs hat geschrieben:Eventuell kann ich auch Dir helfen. Wenn ich es richtig verstehe, benötigst Du ein Programm, welches automatisch nach Aufruf korrupte Daten reparieren kann, damit man es immer wieder laufen lassen kann. Richtig?
? Erstmal brauche ich 'ne Möglichkeit die drei .DBF Dateien so wiederherzustellen, dass ich in jeder der genannten Dateien ein Feld von Typ N von 3 auf 4 Stellen erweitern kann. Daran arbeite ich gerade. Vielleicht komme ich noch mal auf Dein Angebot zurück, ... erstmal sehen was der Tag so bringt.
Gruß,
Magic
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von brandelh »

Das Tool für den Job ist DBU, allerdings wird es mit dem besagten Fehler abbrechen.
Der Aufbau einer DBF ist einfach, nach dem Header stehen alle Daten im Klartext auf der Platte, wobei Zahlen als Ziffern mit führenden Blanks und Dezimalpunkt gespeichert sind.
Wenn also in dem bisherigen 3 stelligen Zahlenfeld Werte stehen, die den Import abbrechen lassen, dann kann man nicht einfach ein "Reparaturtool" drüber laufen lassen und gut ist :!:
Die oben erwähnten Verweise auf die Fehler in der Memodatei (also fehlendes Memofeld ... vielleicht war die Lösung auch von Ulli und nicht von Tom ... :wink: ) lassen zumindest eine DBF entstehen, deren "normale" Felder wohl in Ordnung sind und nur die Memodatei vertauscht / beschädigt wurde, in deinem Fall muss wohl beim Schreiben etwas schief gelaufen sein oder die Datei liegt in defekten Sektoren.

Man kann mit einem entsprechenden Programm (und nur mit diesem) die restlichen Daten umkopieren, aber ob man den Inhalten trauen darf ist eine andere Frage.
Du mußt die fehlerhaften Sätze ansehen, den falschen Inhalt lesen und beurteilen wo das Problem liegt ;-)
Als erstes mußt du die Länge des Headers bestimmen: Header()
Dann skipst du durch die Zeilen und liest das numerische Feld, bis es kracht: => Fehler in Satz x
mit einem Hexeditor oder fopen, fseek etc, kannst du dann an Position Header()+1 * nLetzterKorrekterSatz * Recsize() springen und Recsize() Bytes lesen.
Dies ist nun der auf der Platte befindliche Datensatz. Im ersten Byte ist Platz für die Löschmarkierung, dann kommen die Felder mit der jeweiligen Feldlänge.

Ich würde nun zunächst hingehen und die defekten Datensätze ansehen, eventuell kann man ja die Ursache für den Fehler finden.

PS: in der Hilfe steht "Bei DBF-Dateien ist die tatsächliche Länge eines Datensatzes RecSize() + 1, da in jedem Datensatz ein Byte für die Löschmarkierung (Deleted()-Flag) reserviert ist. ",
das ist falsch, eine DBF mit einem Textfeld a 10 Zeichen gibt RecSize() 11 zurück :-)
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von Koverhage »

Wenn die Feldlänge (alle außer Char ) geändert und im Datensatz Schrott (z.B. alphanumerische Daten anstatt numerischen Daten) scheitert es.
Mit DBU schauen wo Schrott drin steht. Bis zu der Satznummer kopieren und nach dem Schrott weitermachen.

Ab wo der Schrott auftritt lässt sich am schnellsten so feststellen.
Eine neue DBF anlegen, die alte importieren.
Gruß
Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von brandelh »

Ich habe mal ein Beispiel für den Aufbau einer DBF und lowlevel Datenoperationen beigefügt:

Code: Alles auswählen

#include "Gra.ch"
#include "Xbp.ch"
#include "Common.ch"
#include "fileio.ch"
#include "Inkey.ch"

procedure main()
   local aData, nHeader, nRecSize, nZielRec, nH, nPos
   field TextFeld, NumFeld
   dbcreate("test.dbf", {{ "TextFeld" , "C",10,0},;
                         { "NumFeld"  , "N",10,2}})
   use test
   if neterr()
      ? "Fehler"
   else
      nHeader  := Header()
      nRecSize := Recsize()
      nZielRec := 2
      ? "Header():   ", nHeader
      ? "Recsize():  ", nRecSize
      append blank
      replace TextFeld with "Test 1"
      replace NumFeld  with 1
      append blank
      replace TextFeld with "Test 2"
      replace NumFeld  with 2
      append blank
      replace TextFeld with "Test 3"
      replace NumFeld  with 3
      delete
      goto (nZielRec)
      ? recno(),"=",TextFeld,NumFeld,"Löschmarkierung ? ",deleted()
      skip
      ? recno(),"=",TextFeld,NumFeld,"Löschmarkierung ? ",deleted()
      close

      nH := fopen("test.dbf", FO_READWRITE+FO_DENYWRITE )
      IF FError() <> 0
         ? "Fehler beim Öffnen der Datei:", FError()
      ENDIF
      nPos := nHeader + (nZielRec-1) * nRecSize
      fseek(nH, nPos)
      ? nZielRec,"=","'"+FReadStr( nH, nRecSize )+"'"
      // nun steht der Satzzeiger auf dem nächsten Satz !
      ? nZielRec+1,"=","'"+FReadStr( nH, nRecSize )+"'"
   endif
   wait
return
hier die Ausgabe:

Code: Alles auswählen


Header():            98
Recsize():           21
              2 = Test 2           2,00 Löschmarkierung ?  N
              3 = Test 3           3,00 Löschmarkierung ?  J
         2 = ' Test 2          2.00'
         3 = '*Test 3          3.00'
Press any key to continue...
PS: wie man hier sieht braucht man KEIN +1 beim Header() ... und Zahlen haben führende Blanks statt Nullen ...

Das alles ist aber keine "Wartung", sondern eine Fehlerbereinigung.
Gruß
Hubert
Benutzeravatar
Koverhage
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2470
Registriert: Fr, 23. Dez 2005 8:00
Wohnort: Aalen
Hat sich bedankt: 102 Mal
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von Koverhage »

Hallo Hubert,

ändere doch mal einen numerische Wert in der DBF datei via Hexeditor auf einen nicht numerischen Wert.
Dann über DBU die Feldlänge ändern ;-)
Gruß
Klaus
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von brandelh »

Ich meine mich zu erinnern, dass wenn ich ein FELD vom Typ C mit Ziffern als Text nach numerisch ändere der Import abbricht.
Daher denke ich nicht, dass DBU die DBF reparieren kann, aber ich kann mich ja auch irren ;-)

Gerade habe ich es bei meinem Xbase-DBU geprüft, er bricht nicht ab, hat aber überall 0 drinn stehen.
Ob ich das geändert habe oder ob mich meine Erinnerung trübt, wer weiß :?

Auf jeden Fall kann mein DBU die Feldlänge ändern und die Zellen mit falschem Wert werden auf 0 gesetzt.
Da frage ich mich aber, wie die ursprüngliche Fehlermeldung überhaupt entstanden ist, denn auch bei der Anzeige mit anderen Programmen ist in den defekten Feldern immer nur 0,00 8)
Gruß
Hubert
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: Datenbankwartung?

Beitrag von Magic »

Hallo und vielen Dank die bisherigen Anregungen / Ideen und Hilfe.

Komme sehr gut voran.
Gibt es eine andere (mir nicht bekannte) Möglichkeit performanter Datensäte aus einer DBF in eine andere (also eine bereits existierende und leere DBF) zu überführen, als es in einer Schleife mit DbAppend() oder mit DbImport() zu tun.
Ich würde gerne nicht satzweise kopieren wollen, denn das Dauert bei mehr als 3 Mio. Datensätzen und 52 Feldern mir zu lange.
Gruß,
Magic
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von UliTs »

Hallo Magic,

benutz doch im Data Architect ein SQL Statement :-) .

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: Datenbankwartung?

Beitrag von Magic »

UliTs hat geschrieben:benutz doch im Data Architect ein SQL Statement :-) .
Ja, das ist doch 'ne Idee!
Wieso bin ich nicht selber drauf gekommen? :roll: #-o

PS. Zitat heute sogar mit smiley ... =D>
Gruß,
Magic
UliTs
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2828
Registriert: Fr, 10. Feb 2006 9:51
Wohnort: Aachen
Hat sich bedankt: 259 Mal
Danksagung erhalten: 12 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von UliTs »

Und?
Hat alles geklappt?

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15689
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 65 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Datenbankwartung?

Beitrag von brandelh »

Magic hat geschrieben:Ich würde gerne nicht satzweise kopieren wollen, denn das Dauert bei mehr als 3 Mio. Datensätzen und 52 Feldern mir zu lange.
Hi,

ich habe hier mal eine DBF mit 3 Millionen Datensätzen erzeugt, 120 Byte je Satz und EXCLUSIVE geöffnet.
Um eine Minute auf einem modernen Rechner ;-)
Gruß
Hubert
Benutzeravatar
Magic
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 343
Registriert: Mo, 11. Jul 2011 12:01

Re: Datenbankwartung?

Beitrag von Magic »

UliTs hat geschrieben:Und?
Hat alles geklappt?Uli
Ja. Habe es dann doch unter Xbase++ mit DbImport() gemacht.
Hatte nur leider noch Tage nach der Umstellung mit den Auswirkungen einer "kleinen" DB Änderung zu kämpfen.
Da bei uns ja alle so super dokumentiert ist, habe ich in einem Programm einen Indexausdruck übersehen.
Das war echt klasse!
Aber sonst hat die Umstellung geklappt.
Gruß,
Magic
Antworten