Doppelte Datensätze

Zugriff, Engines, Konvertierung. Von ADS über DBF bis zu SQL.

Moderator: Moderatoren

Antworten
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:

Doppelte Datensätze

Beitrag von Koverhage »

Hallo,

vermutlich durch einen defekten Index enthält eine Datenbank doppelte Datensätze.
Wie kann ich die automatisch entfernen bzw. was ist sinnvoll ?
Dies muss ja ohne Index passieren, da sonst ja alle Sätze (zumindest im Index) weg sind.

Wie kann man das verhindern, UNIQUE nützt vermutlich wenig, wenn der Index defekt ist
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von Tom »

Tabelle ohne Index öffnen, temporären Unique-Index erzeugen und öffnen, Datensätze umkopieren, alte Tabelle löschen, neue umbenennen, Indexe neu erzeugen.

So richtig vorstellbar ist es allerdings nicht, dass sich durch einen "fehlerhaften Index" Datensätze verdoppeln.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von brandelh »

Hi,

wenn man den DBEDITOR nutzt (zumindest in meiner aktuellen Version), dann
kommt es zu solchen "doppelten Datensätzen", sobald die Indexreihenfolge
verändert wird. Leider fehlt dabei wohl ein REFRESHALL().
Auf jeden Fall sieht man noch die alte Anzeige, die DBF Reihenfolge darunter
hat sich aber geändert. Sobald man nun ein Feld verläßt, speichert datalink
den angezeigten Inhalt in das Feld und überschreibt den richtigen Inhalt.

Somit waren bei mir zwar tatsächlich Sätze doppelt, aber es fehlten leider auch welche :(

Ich nehme den DBEDITOR nur OHNE INDEX und bin seither sehr misstrauisch.
Leider bin ich aber noch nicht dazu gekommen es besser zu machen :D
Gruß
Hubert
Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 12909
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg
Hat sich bedankt: 19 Mal
Danksagung erhalten: 46 Mal

Re: Doppelte Datensätze

Beitrag von AUGE_OHR »

hi,

Tom hat dir ja schon einen Vorschlag gemacht.
Koverhage hat geschrieben:vermutlich durch einen defekten Index enthält eine Datenbank doppelte Datensätze.
hm ... "defekten Index" hab ich lange nicht mehr gesehen ... Idee "wie" das passiert ist ? schon mal vorher gehabt ?

wie sieht den deine DBESYS aus ... ? :-"
gruss by OHR
Jimmy
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: Doppelte Datensätze

Beitrag von Koverhage »

Hallo,

Tom,
was passiert denn, wen ein dbseek gemacht wird und aufgrund eines defekten Index der Satz nicht gefunden wird
und ein dbappend gemacht wird ?

Jimmy,
DBESYS benutze ich keine, die ntxdbe.ch wird eingebunden also Standard, und ich habe folgende Anweisungen

DbeInfo(COMPONENT_ORDER,DBE_LOCKMODE,LOCKING_EXTENDED)
DbeInfo(COMPONENT_ORDER,NTXDBE_LOCKRETRY,200000)
DbeInfo(COMPONENT_ORDER,NTXDBE_LOCKDELAY,10)
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von Tom »

Hallo, Klaus.
was passiert denn, wen ein dbseek gemacht wird und aufgrund eines defekten Index der Satz nicht gefunden wird
und ein dbappend gemacht wird ?
Okay. Ich nahm an, dass Du diagnostiziert hättest, die Datensätze würden sich irgendwie von selbst verdoppeln.

Wenn man einen Unique-Index anlegt, wird der historisch zuerst gefundene Datensatz indexiert, der folgende nicht mehr. Eine Tabelle mit einem Unique-Index zeigt also den älteren Datensatz an. Die Frage an Dich würde lauten, welcher der "richtigere" ist. Wenn der neuere der richtigere ist, müsstest Du irgendwie vergleichen, zum Beispiel Einzelarrays, die mit Scatter() (leider immer noch nicht dokumentiert, funktioniert aber) erzeugt wurden. Oder, wenn es einen einfachen, ein-eindeutigen Schlüssel gibt, die Datenbank von hinten nach vorne durchsuchen und jeweils mit DbSeek() prüfen, ob es einen anderen Datensatz mit dem gleichen Schlüsselwert gibt - und diesen dann löschen. Gegebenenfalls sogar mehrfach.
Herzlich,
Tom
Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 15697
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Hat sich bedankt: 66 Mal
Danksagung erhalten: 33 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von brandelh »

Bei unserer Datenzusammenführung (von 6 Rechnern auf 1 Server) ließ ich mir alle Daten anzeigen (eigenes Programm),
die ich nicht automatisch zusammenführen konnte (Datumsfelder der letzten Bearbeitung etc.).

Wenn wirklich alles nur doppelt ist, dann reicht die einfache Methode von TOM (UNIQUE INDEX und COPY TO)
wenn nicht, heist es im Einzelfall prüfen.
Gruß
Hubert
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Doppelte Datensätze

Beitrag von Markus Walter »

Tom hat geschrieben:...zum Beispiel Einzelarrays, die mit Scatter() (leider immer noch nicht dokumentiert, funktioniert aber) erzeugt wurden.
Hi Tom,

könntest Du kurz was zu scatter schreiben? Mir fehlt da der Überblick...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14658
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von Jan »

Klaus,

hast Du Dir mal das hier angesehen?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Martin Altmann
Foren-Administrator
Foren-Administrator
Beiträge: 16517
Registriert: Fr, 23. Sep 2005 4:58
Wohnort: Berlin
Hat sich bedankt: 111 Mal
Danksagung erhalten: 48 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von Martin Altmann »

Markus,
scatter ist das Gegenstück zu gather - beides findest Du in der Hilfe bei der Volltextsuche.
Beides wertet die datalinks aus - das eine (scatter) den Teil zum Lesen aus der DB und das andere (gather) den Teil zum Zurückschreiben in die DB.

Viele Grüße,
Martin
:grommit:
Webseite mit XB2.NET und ausschließlich statischem Content in Form von HTML-Dateien: https://www.altem.de/
Webseite mit XB2.NET und ausschließlich dynamischem Content in Form von in-memory-HTML: https://meldungen.altem.de/

Mitglied der XUG Osnabrück
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Markus Walter
Programmier-Gott
Programmier-Gott
Beiträge: 1018
Registriert: Di, 24. Jan 2006 10:22
Wohnort: Saarland

Re: Doppelte Datensätze

Beitrag von Markus Walter »

Hi Martin,

danke.

Ich habe mir das mal angesehen. Ich hatte gehofft, das wären Funktionen um "schnell" einen kompletten Datensatz in einen Array einzulesen bzw. zu schreiben. Aber ein Blick in den Quellcode zeigt, dass die letzendlich nichts anderes machen, als "normale, feldweise Zugriffe"...
Gruß
Markus

Mitglied der XUG Saarland-Pfalz
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: Doppelte Datensätze

Beitrag von Koverhage »

Jan,
ja habe das aufmerksam verfolgt ;-)
Leider bzw. glücklicherweise trifft das bei mir nicht zu.
Werde wohl doch ein Programm machen müssen, welche mir die doppelten Daten anzeigt und ich dann sagen kann,
der Satz kann gelöscht werden.
Habe gehofft das jemand ein Tool kennt, wo ich
1. die Felder auswählen kann, die doppelt vorhanden sein müssen
z.B. Rechnungsnummer + Position
2. sagen kann, markiere mir alle die eine gewählte Bedingung enthalten (ähnlich locate oder set filter und markiere die)
3. löschen der gewählten/markierten Sätze
Gruß
Klaus
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9367
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 102 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Doppelte Datensätze

Beitrag von Tom »

Code: Alles auswählen

FUNCTION CleanDataBase()
SET DELETED OFF
USE MyTABLE INDEX MyTABLE /* Rechnungnr+Position */ NEW EXCLUSIVE
DO WHILE !Eof()
  IF !Deleted()
    EraseOthersFound()
  ENDIF
  DbSkip()
ENDDO
RETURN nil

PROC EraseOthersFound()
LOCAL nRec := Recno(), cLookFor := MyTABLE->Rechnr+MyTABLE->Position
DbSeek(cLookFor)
DO WHILE MyTABLE->Rechnr+MyTABLE->Position = cLookFor .AND. !Eof()
  IF !Recno() = nRec
    DELETE
  ENDIF
  DbSkip()
ENDDO
DbGoto(nRec)
RETURN
Ins Blaue geschrieben, müsste aber so oder ähnlich funzen.

Edit: Das hier macht genau dasselbe:

Code: Alles auswählen

USE MyTable NEW EXLUSIVE
INDEX ON Rechnr+Position TO MyTABLE UNIQUE
COPY TO TEMP
SET INDEX TO
ZAP
APPEND FROM TEMP
Herzlich,
Tom
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: Doppelte Datensätze

Beitrag von Koverhage »

Hallo Tom,

danke.

Habe auch das hier gefunden:

Code: Alles auswählen

*+²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
*+
*+    Source Module => H:\DLOADS\FTP\TEMP\DUPL.PRG
*+
*+    Functions: Function dupl()
*+               Function MYKEY()
*+
*+       Tables: use ( Mfile )
*+
*+      Indexes: index on MYKEY() to DUMMY1
*+
*+    Reformatted by Click! 1.11 on Sep-21-1997 at 10:46 pm
*+
*+²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²

/*
I have Summer'87 code for listing duplicate records in a dbf. I'll post it
if you want.

1. It asks for the file name
2. It lists the fields, and then asks for which field(s) combination
should be unique.
3. It prints a list of the record numbers containing duplicate keys.

Actually it's not too long. I'll post it now...

Fred Zuckerman
ZuckermanF@aol.com
San Diego
*/

* DUPL.PRG
* Finds Records With Duplicate Key Fields

*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
*+    Function dupl()
*+
*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
Procedure Main()

CLEAR

Mfile := "C:\DBASE\              "
@  1,  5 say "ENTER FILENAME " get Mfile        

read

use ( Mfile )

DECLARE Fname[ fcount() ], Ftype[ fcount() ], Flen[ fcount() ], Fdec[ fcount() ], Fnum[ 5 ]

afill( Fnum, 0 )
afields( Fname, Ftype, Flen, Fdec )

ROW := 2
COL := 0
for i := 1 to fcount()
   @ ROW, COL     say str( i, 3 ) + "."
   @ ROW, COL + 5 say Fname[ i ]                
   ROW ++
   IF ROW >= 20
      ROW := 2
      COL += 15
   endif
next

@ 22,  5 say "ENTER FIELDS TO CHECK"                  
@ 22, 30 get Fnum[ 1 ]               pict '###'
@ 22, 35 get Fnum[ 2 ]               pict '###'
@ 22, 40 get Fnum[ 3 ]               pict '###'
@ 22, 45 get Fnum[ 4 ]               pict '###'
@ 22, 50 get Fnum[ 5 ]               pict '###'

read

@ 23,  5 say "INDEXING..."         
index on MYKEY() to DUMMY1

go top
@ 24,  5 say "PRINTING..."         
set device to print
set printer to x.x
@  1,  5 say dtoc( date() ) + " Duplicates Found In " + rtrim( Mfile ) + " Fields " + ;         
        iif( Fnum[ 1 ] > 0, Fname[ Fnum[ 1 ] ], "" ) + ;
        iif( Fnum[ 2 ] > 0, "+" + Fname[ Fnum[ 2 ] ], "" ) + ;
        iif( Fnum[ 3 ] > 0, "+" + Fname[ Fnum[ 3 ] ], "" ) + ;
        iif( Fnum[ 4 ] > 0, "+" + Fname[ Fnum[ 4 ] ], "" ) + ;
        iif( Fnum[ 5 ] > 0, "+" + Fname[ Fnum[ 5 ] ], "" )
LINE := 3

do while !eof()
   Mrec1 := recno()
   F1    := MYKEY()
   ***
   skip
   ***
   Mrec2 := recno()
   F2    := MYKEY()
   ***
   IF F2 == F1
      @ LINE,  1 say str( Mrec1, 5 ) + " AND " + str( Mrec2, 5 ) + "      = " + F1         
      LINE ++
   endif
enddo

eject

set device to screen

close DATABASES
clear memory
erase DUMMY1.NTX

return

*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
*+    Function MYKEY()
*+
*+    Called from ( dupl.prg     )   3 - function dupl()
*+
*+±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
*+
function MYKEY

K := ''
for i := 1 to 5
   IF Fnum[ i ] = 0
      exit
   endif
   Fval := Fname[ Fnum[ i ] ]
   K    += "+"
   do case
   case Ftype[ Fnum[ i ] ] = 'C'
      K += &Fval
   case Ftype[ Fnum[ i ] ] = 'N'
      K += str( &Fval, Flen[ Fnum[ i ] ], Fdec[ Fnum[ i ] ] )
   case Ftype[ Fnum[ i ] ] = 'D'
      K += dtoc( &Fval )
   case Ftype[ Fnum[ i ] ] = 'L'
      K += iif( &Fval, ".T.", ".F." )
   endcase
next

return substr( K, 2 )

*+ EOF: DUPL.PRG
Gruß
Klaus
Antworten