Das Forentreffen 2018 findet am 20./21. April in Dresden statt. Weitere Infos hier
Zur Homepage des Deutschsprachige Xbase-Entwickler e. V.
Xbase++-Wiki des Deutschsprachige Xbase-Entwickler e. V.

Vorgehensweise bei Unique Index

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

Moderator: Moderatoren

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 11:07

Gerade habe ich folgendes Problem festgestellt: Wir haben eine dbf mit einen Unique-Index. Die wird etwas aufwändig gepflegt, wenn Datensätze geändert werden sollen.
- Zu ändernde Datensätze mit eine Sperrflag versehen (spezielles Datenbankfeld mit dem Bearbeiternamen füllen)
- Datensätze exportieren in eine Bearbeitungs-dbf
- Geänderte Datensätze zurückkopieren
- Datensätze mit Sperrkennzeichen löschen.

Dadurch ist gewährleistet, das auch nach einem Programmabsturz die Daten immer vorhanden sind. Entweder die alten, unveränderten, oder die neuen. Zur Not auch doppelt, aber immer unterschieden durch das Sperrkennzeichen.

Diese Vorgehensweise ist auch nicht einfach abzuändern, ich muß also prinzipiell erstmal damit klar kommen.

Nun das Problem. Der Index ist Unique. Hat also immer den ersten Datenstz im Index stehen. Wenn ich den nun lösche, ist anscheinend jeder Datensatz mit diesem Wert im Indexfeld raus. Warum? Wie kann ich das umgehen?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 11:09

DbSetOrder(0) - alle Indexe sind aktiv, aber keiner ist führend. Damit werden auch gedoppelte Einträge, die ein UNIQUE-Index eigentlich ausschließt, berücksichtigt.
Herzlich,
Tom

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 16897
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel

Re: Vorgehensweise bei Unique Index

Beitrag von Manfred » Mo, 02. Apr 2012 11:18

Oder einen 2.Index mitführen, der nicht UNique ist.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 11:20

Moin Tom,

öhm, versteh ich jetzt nicht.

Alle Indizee sind geöffnet (auch der Unique), bei der ganzen Löschaktion ist ein anderer Index aktiv (nicht der Unique), da ich hier die abzuarbeitendenen Datensetze mit SCOPE eingrenze.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 11:21

Moin Manfred,

da laufen 7 oder 8 Indizee parallel mit. nicht nur der Unique. Und alle sind immer geöffnet.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 16897
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel

Re: Vorgehensweise bei Unique Index

Beitrag von Manfred » Mo, 02. Apr 2012 11:22

Mit einem 2. meinte ich nicht, dass einer zu wenig ist, sondern den Unique parallel führen, aber ohne Unique eben.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 11:22

Im Prinzip hat man immer einen Index automatisch "dabei", nämlich die Datensatznummer. Keine Suche ist schneller als diese (DbGoto()). Wenn man nicht-eindeutig über einen Wert suchen will, für den es ansonsten nur einen UNIQUE-Index gibt, muss man allerdings tatsächlich einen weiteren Index aufbauen.

Was mich aber ein wenig wundert, ist die Mitteilung, die Löschung eines Datensatzes, der mit einem UNIQUE-Index referenziert ist, würde auch alle (anderen) Datensätze löschen, die dem Wert entsprechen. Das widerspricht dem gesamten Datenbankmodell; man "steht" immer nur auf einem Datensatz - bei UNIQUE eben dem (historisch) ersten, der mit diesem Wert erfasst wurde. Wenn man den löscht, müsste eigentlich der nächste Datensatz "auftauchen", der dem Wert entspricht. Es sei denn, die Löschroutine ist falsch programmiert.
Herzlich,
Tom

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 11:26

Tom,

genau das hatte ich auch erwartet - wird der Satz mit dem Unique-Zeiger gelöscht, kommt der nächste mit dem passenden Wert in den Index. Vor Allem, weil das Löschen nicht nur Löschen bedeutet, sondern vorher wird der Indexwert noch auf 0 gesetzt. Und es bleiben immer noch Sätze über mit dem Indexwert, denn es gibt ja die geänderten zurückkopierten.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 11:26

Hä?

Du löschst in einer Tabelle, die x Indexe hat, davon ist einer UNIQUE. Und der ist beim Löschen nicht aktiv? Oha. Du denkst aber daran, ihn nach dem Löschen neu zu erzeugen, ja? Was hat die Frage dann mit UNIQUE zu tun? Grundsätzlich sollte man bei Änderungen/Löschungen immer alle Indexe geöffnet haben, sonst muss man sie manuell pflegen.

Du hast da irgendwo ein Problem in Deiner Löschroutine. Ein bisschen Beispielcode könnte nicht schaden.
Herzlich,
Tom

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 11:48

Tom,

was meinst Du mit "Index ist nicht aktiv"? Alle zur dbf gehörenden Indizee sind offen. Und werden dadurch natürlich auch mitgeführt. Auch der Unique ist offen. Sollte also ebenfalls aktualisiert werden. Oder mißverstehe ich da etwas Grundlegendes?

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 11:53

Hallo, Jan.

Ich verstehe Deine Problembeschreibung nach wie vor nicht, vermute aber, dass Du in ein simples Problem läufst. Du hast eine Tabelle geöffnet, irgendein Index ist aktiv. Jetzt setzt Du beispielsweise ein Scope auf diese Tabelle. Du bist nun der Meinung, alle Datensätze, die der Scope-Bedingung entsprechen, einfach so löschen zu können:

Code: Alles auswählen

DO WHILE !Eof()
  DbDelete()
  DbSkip()
ENDDO
Das ist aber nicht richtig. Du löschst einen Datensatz, der dem Scope entspricht, also dem führenden Index genügt. Damit fällt dieser Datensatz automatisch aus dem Scope, nur nicht mit SET DELETED OFF. Der Datensatzzeiger bewegt sich automatisch weiter auf den nächsten Datensatz, sonst wäre der Scope falsch. Du überspringst also immer einen Datensatz und löschst nur die Hälfte. :wink:
Herzlich,
Tom

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 12:08

Hallo Tom,

nene, da achte ich schon drauf. Das Löschen funktioniert einwandfrei. Kein Datensatz wird übersprungen. Aber es steht auch keiner der übriggeblieben, also geänderten, Sätze mehr im Unique-Index. Und DAS ist das Problem.

Wie wir beide oben schon gemutmaßt haben, sollte beim Löschen des Datensatzes, der den Unique-Zeiger hat, der Zeiger auf den nächsten Satz gehen, der der Indexbedingung entspricht (sofern es noch einen weiteren gibt). Tut der aber offensichtlich nicht. Und DAS Problem muß ich lösen.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
AUGE_OHR
Marvin
Marvin
Beiträge: 10522
Registriert: Do, 16. Mär 2006 7:55
Wohnort: Hamburg

Re: Vorgehensweise bei Unique Index

Beitrag von AUGE_OHR » Mo, 02. Apr 2012 12:14

Jan hat geschrieben:genau das hatte ich auch erwartet - wird der Satz mit dem Unique-Zeiger gelöscht, kommt der nächste mit dem passenden Wert in den Index.
... probiere mal diesen Code

Code: Alles auswählen

PROCEDURE MAIN
LOCAL i,j

   CLS
   SET DELETE ON

   IF !FILE("TEST.DBF")
      C_TEST("TEST.DBF")
   ENDIF

   USE TEST.DBF EXCLUSIVE
   ZAP

   FOR i := 1 TO 3
      j := 1
      FOR j := 1 TO 16
         APPEND BLANK
         REPLACE TEXT   WITH CHR(j+64)
         REPLACE NUMMER WITH RECNO()
      NEXT
   NEXT
   GO TOP
   BROWSE()

   GO TOP
   INDEX ON TEST->TEXT TO TEST.NTX UNIQUE
   BROWSE()

   SEEK "J"
   IF FOUND()
      ? "l”sche record :"+STR(RECNO())
      WAIT
      DELETE
   ENDIF
   BROWSE()

   SEEK "J"
   IF FOUND()
      ? "GEFUNDEN ??? ...record :"+STR(RECNO())
      WAIT
   ELSE
      ALERT("NICHT GEFUNDEN !!!")
   ENDIF
   BROWSE()

RETURN

FUNCTION C_TEST(datei,alias,id)
LOCAL p,field_list:={}
  if valtype(datei)!="C"
    datei="TEST.DBF"
  endif
  if valtype(alias)!="C"
    p=at(".",datei)
    alias=if(p>0,substr(datei,1,p-1),datei)
  endif
  if valtype(id)!="N"
    id=0
  endif
  select (id)
  if !file(datei)
    aadd(field_list,{"TEXT","C",10,0})
    aadd(field_list,{"NUMMER","N",10,0})
    dbcreate(datei,field_list)
  endif
return(.t.)
da "rückt nichts auf" !
gruss by OHR
Jimmy

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 12:21

Jimmy,

ist ja nett, das Du den ganzen Code hier schreibst. Aber wie bitte löst das jetzt mein Problem? Nur weil EIN Datensatz in einer dbf gelöscht wird, dürfen doch nicht alle Datensätze, die den gleichen Indexwert haben, aus dem Unique-Index rausfliegen!

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 16897
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel

Re: Vorgehensweise bei Unique Index

Beitrag von Manfred » Mo, 02. Apr 2012 12:24

nochmal kurz nachgefragt:

Wird der Satz nur als gelöscht gekennzeichnet, oder wird der auch "genullt"? Das konnte ich jetzt aus dem ganzen Text nicht genau erkennen.
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 12:26

Manfreds Nachfrage ist so uninteressant nicht. Wenn man Inhalte ändert, ändert sich natürlich auch die Datensatzfolge gemäß kontrollierendem Index. Das ist auch so eine Falle.
Herzlich,
Tom

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 12:28

Übrigens, Jimmy:

Tabelle Kunden, Index UNIQUE auf Name. Tabelle enthält "Meier", "Meier", "Müller", "Schulz".

Code: Alles auswählen

DbSeek('Meier') -> Datensatz 1
DbSkip() -> Datensatz 3

DbGoTo(1)
DbDelete()
DbSeek('Meier') -> Datensatz 2
Herzlich,
Tom

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 12:32

Wie ich oben schon schrieb, wird der erst genullt, dann gelöscht. Aber Das kann doch nicht der Grund sein, das der aus dem Unique-Index komplett rausfliegt! Es gibt immerhin noch reihenweise (ungelöschte) Sätze, die ebenfalls den Wert haben. Die sind danach aber unauffindbar, wenn ich den Unique aktiviere. Nach meinem bescheidenen Vorstellungsvermögen ist das aber grundsätzlich falsch.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 16897
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel

Re: Vorgehensweise bei Unique Index

Beitrag von Manfred » Mo, 02. Apr 2012 12:41

Nur mal so eingeworfen, hast Du schonmal versucht ein DbSkip(0) oder irgendeine Datensatzbewegeung danach zu machen? Vielleicht ist es ja so wie wie bei Filter, das man erstmal das Teil wieder aktualisieren muß?
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13753
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von brandelh » Mo, 02. Apr 2012 12:45

Hallo Jan,

dein Verständnis für Indexdateien ist falsch !

Beim Anlegen werden alle Datensätze durchsucht und in den Index einbebaut, die der FOR / WHILE Bedingung entsprechen.
Ändert sich ein Indexkey Datenfeld, werden die Verweise auf den Vorgänger, Nachfolger neu gesetzt.
Beim Löschen ist es genauso, der Vorgänger wird mit dem Nachfolger verbunden, der einzelne Satz fliegt aus dem Index raus
(bei FOR ! deleted), bzw. wird übersprungen.
Neue Datensätze werden durch APPEND in die DBF und den Index eingefügt.

Was ist nun bei UNIQUE ?

Der einzelne Satz mit dem KEY fliegt raus oder wird übersprungen, der Vorgänger wird mit dem Nachfolger verbunden.
Eine erneute SUCHE ob eventuell noch andere mit dem Schlüssel vorhanden sind findet nicht statt !
Dafür wäre ja ein Reindex nötig, der sehr viel Zeit benötigt !

Du könntest einen REINDEX auf dem UNIQUE machen oder die Indexe nach Löschung neu aufbauen ...
oder überdenken ob du ohne auskommst !
Gruß
Hubert

Benutzeravatar
Manfred
Foren-Administrator
Foren-Administrator
Beiträge: 16897
Registriert: Di, 29. Nov 2005 16:58
Wohnort: Kreis Wesel

Re: Vorgehensweise bei Unique Index

Beitrag von Manfred » Mo, 02. Apr 2012 12:50

Hubert,

ich glaube da hast Du Jan falsch verstanden, oder wie auch immer. Er meint sicherlich nur, dass der nächste (so wie Du beschreibst) nachrücken müßte. Und das sollte ja wohl sein. Aber die Frage ist, warum es nicht aktualisiert wird?
Gruß Manfred
Mitglied der XUG Leverkusen
Mitglied der XUG Osnabrück
Schatzmeister des Deutschsprachige Xbase-Entwickler e.V.

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13753
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von brandelh » Mo, 02. Apr 2012 12:53

Manfred hat geschrieben:Hubert,
ich glaube da hast Du Jan falsch verstanden, oder wie auch immer.
Er meint sicherlich nur, dass der nächste (so wie Du beschreibst) nachrücken müßte. Und das sollte ja wohl sein. Aber die Frage ist, warum es nicht aktualisiert wird?
Ne Manfred,
du bist auch auf dem Holzweg ;-)
Im Index ist genau ein Eintrag pro Datensatz !
Bei UNIQUE wird kein zweiter Eintrag mit dem gleichen Indexschlüssel angelegt, die Indexdatei kennt also keine weiteren Datensätze mit gleichem Index.
Wenn der einzelne Datensatz der im Index ist nun per set deleted on übersprungen wird, oder mit FOR ! DELETED() direkt rausfliegt
wird da nicht noch gesucht ob eventuell ein anderer passen könnte ! Das wäre nämlich ein implizietes reindex, was viel zu lahm ist und eventuell auch die Rechte nicht passen !
Gruß
Hubert

Benutzeravatar
brandelh
Foren-Moderator
Foren-Moderator
Beiträge: 13753
Registriert: Mo, 23. Jan 2006 20:54
Wohnort: Germersheim
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von brandelh » Mo, 02. Apr 2012 12:57

Man könnte einem CUSTOM Index das gewünschte Verhalten beibringen, aber ich würde mir eher überlegen den normalen Index zu nutzen
und das UNIQUE wenn nötig über eine Filterfunktion zu realisieren.
Gruß
Hubert

Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 6793
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Tom » Mo, 02. Apr 2012 12:58

Nein, Hubert hat Recht.

Ich erzeuge eine Tabelle mit 4 Einträgen, Index UNIQUE auf "NAME", wie im obigen Beispiel. Ich aktiviere den Index, wobei keine Rolle spielt, ob er führend ist oder nicht. Dann lösche ich den ersten Eintrag "Meier". Schalte ich auf den führenden UNIQUE-Index, wird mir jetzt auch der zweite "Meier" nicht angezeigt. Er ist aber NICHT GELÖSCHT, er fehlt nur im Index - tatsächlich gelöscht (Markierung im Datensatz) ist lediglich der erste Meier. Trotzdem ist der zweite Datensatz weg, solange der Index aktiv und führend ist - mit SET ORDER TO 0 erscheint er wieder. Wenn ich die Tabelle ohne Index öffne, sehe ich den zweiten Meier ebenfalls. Nach einem Reindex sehe ich ihn auch wieder. Aber ein UNIQUE-Eintrag wird nicht "nachgerückt".
Herzlich,
Tom

Benutzeravatar
Jan
Foren-Administrator
Foren-Administrator
Beiträge: 12225
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Kontaktdaten:

Re: Vorgehensweise bei Unique Index

Beitrag von Jan » Mo, 02. Apr 2012 13:05

Tom,

nur zum Verständnis: Wenn ich den ersten und den zweiten und den dritten Satz lösche, dann ein DbSetOrder(0) mache, und dann auf den Unique-Index gehe, dann wird der vierte Datensatz (bzw. dann natürlich der neue erste) angezeigt?

Ich frag nur, weil mir das etwas nach geheimnissvolle magische Blackbox klingt.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Vorsitzender des Deutschsprachige Xbase-Entwickler e. V.

Antworten