Suche in großen Datenbeständen

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

Moderator: Moderatoren

Benutzeravatar
azzo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 483
Registriert: So, 28. Mär 2010 19:21
Danksagung erhalten: 11 Mal

Re: Suche in großen Datenbeständen

Beitrag von azzo »

Hallo Werner,
ich nehme an, dass du den Code in ein bestehendes Programm eingebaut hast.
Wenn ja, kann es sein, dass du dort die dbf-Datei vorher exklusive öffnest.
mfg
Otto
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

ja
nein
:-)
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
azzo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 483
Registriert: So, 28. Mär 2010 19:21
Danksagung erhalten: 11 Mal

Re: Suche in großen Datenbeständen

Beitrag von azzo »

Hallo Joachim,
danke für deine Info. Sehr interessant. Ich habe ja deshalb die Werte gepostet, um zu sehen, was überhaupt möglich ist.
Es ist schon länger her, dass ich ADS Server hier bei uns getestet habe.
Kann man Volltext-Index auch verwenden, wenn man weiterhin dbf-Dateien verwendet.
Mfg
Otto
Benutzeravatar
azzo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 483
Registriert: So, 28. Mär 2010 19:21
Danksagung erhalten: 11 Mal

Re: Suche in großen Datenbeständen

Beitrag von azzo »

Hallo Werne,
sicherheitshalber die Frage:
Schreib-/leserechte hast du?
mfg
Otto
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: Suche in großen Datenbeständen

Beitrag von UliTs »

Hallo Joachim,

toll, dass Du Dich auch im xBase++-Forum angemeldet hast :wave: :thumbright: :thumbleft: !
Ich kann nur bestätigen, was Joachim schreibt: mit dem ADS gehen solche Suchen (auch in MEMO-Feldern!) rasend schnell!

Otto: man kann die Suche auch mit dbf-Dateien verwenden! In Verbindung mit xBase++ ist sicher die Benutzung von DBF-CDX-Tabellen die beste und einfachste Art!

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Tom
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 9356
Registriert: Do, 22. Sep 2005 23:11
Wohnort: Berlin
Hat sich bedankt: 101 Mal
Danksagung erhalten: 361 Mal
Kontaktdaten:

Re: Suche in großen Datenbeständen

Beitrag von Tom »

Ja, die ADS-Filterfunktionen sind unglaublich rasant. Nur eben direkt nutzen, nicht einfach "SET FILTER ..." machen und auf die ADSDBE hoffen. Die ist nämlich keineswegs <hüstel> irgendwie optimiert.
Herzlich,
Tom
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: Suche in großen Datenbeständen

Beitrag von nightcrawler »

UliTs hat geschrieben:toll, dass Du Dich auch im xBase++-Forum angemeldet hast
Lese hier schon seit einiger Zeit mit ;)
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

azzo hat geschrieben:Hallo Werne,
sicherheitshalber die Frage:
Schreib-/leserechte hast du?
Ja. Steht eigentlich alles in meiner Nachricht.
es grüßt

Werner

<when the music is over, turn off the lights!>
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: Suche in großen Datenbeständen

Beitrag von UliTs »

Tom hat geschrieben:Ja, die ADS-Filterfunktionen sind unglaublich rasant. Nur eben direkt nutzen, nicht einfach "SET FILTER ..." machen und auf die ADSDBE hoffen. Die ist nämlich keineswegs <hüstel> irgendwie optimiert.
Hallo Tom,
ich gebe Dir zum größtenteils Recht!
Ich wüsste gar nicht, wie man die Full Text Search mit der ADSDBE machen kann.
Allerdings geht auch SET FILTER in Verbindung mit der ADSDBE sehr schnell, wenn man den Filter geschickt angibt, z.B. keine Variablen im Filter verwenden sondern stattdessen die Werte mittels Macro-Operator berechnen lassen.

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: Suche in großen Datenbeständen

Beitrag von nightcrawler »

UliTs hat geschrieben:Ich wüsste gar nicht, wie man die Full Text Search mit der ADSDBE machen kann.
auch mit SET FILTER ... soweit ich weiß, schickt die ADSDBE die Filteranfrage an den Server. Liefert der einen Fehler, wird es lokal auszuwerten versucht.
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
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: Suche in großen Datenbeständen

Beitrag von UliTs »

Gute Idee!
Weißt Du, ob man die Fehlermeldung vom Server abfragen kann, um mitzubekommen, ob die Auswertung lokal gemacht wird (klar: wenn es bei großen Datenmengen langsam ist -> Lokal :D ).

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
nightcrawler
1000 working lines a day
1000 working lines a day
Beiträge: 650
Registriert: Di, 24. Apr 2012 16:33
Wohnort: 72184 Weitingen
Hat sich bedankt: 3 Mal
Danksagung erhalten: 96 Mal
Kontaktdaten:

Re: Suche in großen Datenbeständen

Beitrag von nightcrawler »

Soviel Xbase'ler bin ich leider nicht:(
--
Joachim
Joachim Dürr Softwareengineering
https://www.jd-engineering.de
Benutzeravatar
Jan
Marvin
Marvin
Beiträge: 14651
Registriert: Fr, 23. Sep 2005 18:23
Wohnort: 49328 Melle
Hat sich bedankt: 21 Mal
Danksagung erhalten: 88 Mal
Kontaktdaten:

Re: Suche in großen Datenbeständen

Beitrag von Jan »

Kann ja noch werden :lol:

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

Hat jemand mal den Code von azzo selber getestet? Selbst das geht bei mir nicht:

Code: Alles auswählen

use artikel.dbf shared
? alias()
cText := memoread("artikel.dbf")
? len(cText)
Der Pfad passt.
es grüßt

Werner

<when the music is over, turn off the lights!>
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: Suche in großen Datenbeständen

Beitrag von UliTs »

Versuch es mal ohne den use-Befehl.
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

:) Dann hätte der Code ja keinen Sinn! Es geht um eine schnelle Suche in einer geöffneten DBF. Memoread liest read-only, die DBF ist shared geöffnet, es müsste gehen. Bei azzo funktioniert es ja offensichtlich.
es grüßt

Werner

<when the music is over, turn off the lights!>
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2824
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 95 Mal
Danksagung erhalten: 13 Mal

Re: Suche in großen Datenbeständen

Beitrag von georg »

Hallo, Werner -


der Code mag passen, aber auch die Grösse? Eventuell ist Deine Datei zu gross, um in einem Happen in den Speicher zu passen.

Wie wäre es mit dem klassischen

Code: Alles auswählen

nHandle := fOpen("Artikel.DBT", FO_SHARED)
IF nHandle > 0
  nSize := fSize(nHandle)
  cLine := Space(nSize)
  fRead(nHandle, @cLine, nSize)
  fClose(nHandle)
ELSE
  nError := fError()
  ConfirmBox(, "Fehlercode " + Str(nError) + " beim Öffnen", "Fehler", XBPMB_OK, XBPMB_CRITICAL)
ENDIF
Eventuell liegt es ja am Öffnen, oder aber an der Grösse, die der Buffer benötigt.
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

Servus Georg,

an der Größe liegt es nicht, das hatte ich schon getestet. Da käme auch eine andere Fehlermeldung.

Deshalb nochmal die Frage: Hat das so schon mal jemand getestet, ein Erfolgreiches memoread() auf die shared-geöffnete Dbf wie oben beschrieben?
es grüßt

Werner

<when the music is over, turn off the lights!>
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: Suche in großen Datenbeständen

Beitrag von brandelh »

Hi,
du hättest ja ein kleines Testprogramm liefern können ;-)
Ich habe es dennoch probiert, ich bin halt neugierig :D

MEMOREAD() funktioniert NICHT auf geöffneten DBF Dateien.
Bei DBT würde ich das Verfahren aber erst gar nicht einsetzen, denn die Zuordnung der Daten ist sehr umständlich und wer weiß wie intern verworfene / verkettete Seiten (512 Byte Block) behandelt werden ...

Code: Alles auswählen

#include "Fileio.ch"
#include "common.ch"
function main()
   local cTxt, nH
   cls
   set alternate to Protokoll.txt
   set alternate on
   ? "Test mehrfache Íffnung on DBF"
   ?
   ? "FSIZE() meldet: ", fsize("DRU_CODE.DBF"), "Byte"
   use DRU_CODE
   if neterr()
      ? "NETERR()"
   else
      cTxt := memoread("DRU_CODE.DBF")
      ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," MEMOREAD()"
      cTxt := NIL
      cTxt := File2Str("DRU_CODE.DBF")
      ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," File2Str()"
      cTxt := NIL
      nH := fopen( "DRU_CODE.DBF", FO_READ + FO_SHARED ) // FO_READ + FO_SHARED = Standardwert
      if FError() <> 0
         ? "Fehler beim Öffnen der Datei:  nH",nH," FError():",FError()
      else
         ? "FSIZE() meldet: ", fsize(nH), "Byte"
         fclose(nH)
      ENDIF
      ? "Was passiert nach RLOCK()"
      if rlock()
         ? "RLOCK() ist OK"
         cTxt := memoread("DRU_CODE.DBF")
         ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," MEMOREAD()"
         cTxt := NIL
         cTxt := File2Str("DRU_CODE.DBF")
         ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," File2Str()"
         cTxt := NIL
         nH := fopen( "DRU_CODE.DBF", FO_READ + FO_SHARED ) // FO_READ + FO_SHARED = Standardwert
         if FError() <> 0
            ? "Fehler beim Öffnen der Datei:  nH",nH," FError():",FError()
         else
            ? "FSIZE() meldet: ", fsize(nH), "Byte"
            fclose(nH)
         ENDIF
         unlock
      else
         ? "RLOCK() - Fehler !"
      endif
      ? "Was passiert nach FLOCK()"
      if Flock()
         ? "FLOCK() ist OK"
         cTxt := memoread("DRU_CODE.DBF")
         ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," MEMOREAD()"
         cTxt := NIL
         cTxt := File2Str("DRU_CODE.DBF")
         ? "LEN() meldet:   ", len(cTxt), "Byte", "USED():",used()," File2Str()"
         cTxt := NIL
         nH := fopen( "DRU_CODE.DBF", FO_READ + FO_SHARED ) // FO_READ + FO_SHARED = Standardwert
         if FError() <> 0
            ? "Fehler beim Öffnen der Datei:  nH",nH," FError():",FError()
         else
            ? "FSIZE() meldet: ", fsize(nH), "Byte"
            fclose(nH)
         ENDIF
         unlock
      else
         ? "RLOCK() - Fehler !"
      endif


   endif
   wait
return NIL

*---------------------------------------------------------------------------------------------
function File2Str(cFile,nStartPos,nLen,nError)      // memoread() könnte Umwandeln !!!
   local nHandle, cBuffer, nReadBytes,nSeekPos      // nError muss per Referenz übergeben werden
   cBuffer    := ""
   nReadBytes := 0
   DEFAULT nStartPos TO 1    // normalerweise will man ab dem 1. Zeichen.
   DEFAULT nLen      TO 0    // 0 steht für keine Begrenzung
   if nStartPos < 1
      nStartPos := 1
   endif
   nError  := 0              // 0 steht für keinen Fehler
   nHandle := FOpen(cFile)
   if nHandle = -1
      nError := FError()
   else
      if nLen=0
         nLen := FSize( nHandle )
      endif
      if nStartPos > 1
         nSeekPos := FSeek( nHandle, nStartPos-1 )
         if nSeekPos <> nStartPos-1
            nError := -2
         endif
      endif
      cBuffer    := space(nLen)
      nReadBytes := FRead( nHandle, @cBuffer, nLen)
      if nReadBytes < nLen    // eventuell kein Fehler, sondern nur weniger Daten verf³gbar.
         nError := FError()
      endif
   endif
   FClose(nHandle)
return left(cBuffer,nReadBytes)
Und hier das Ergebnis:

Code: Alles auswählen


Test mehrfache Öffnung on DBF

FSIZE() meldet:       29379 Byte
LEN() meldet:             0 Byte USED(): J  MEMOREAD()
LEN() meldet:         29379 Byte USED(): J  File2Str()
FSIZE() meldet:       29379 Byte
Was passiert nach RLOCK()
RLOCK() ist OK
LEN() meldet:             0 Byte USED(): J  MEMOREAD()
LEN() meldet:         29379 Byte USED(): J  File2Str()
FSIZE() meldet:       29379 Byte
Was passiert nach FLOCK()
FLOCK() ist OK
LEN() meldet:             0 Byte USED(): J  MEMOREAD()
LEN() meldet:         29379 Byte USED(): J  File2Str()
FSIZE() meldet:       29379 Byte
Press any key to continue...
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

Servus Hubert,

ich hatte doch ein Beispiel gepostet :wink:

Durch Deinen Code hab ich was entdeckt: Ich hatte doch geschrieben, dass das Öffnen einer shared-geöffneten Dbf mittels low-level-Filefunktion ebenfalls den Fehler 32 bringt. Bei Deinem Beispiel war das ja nicht. Habs gefunden, es liegt am

Code: Alles auswählen

FO_READ+FO_DENYNONE
In meinen low-levels benutzte ich bisher nur

Code: Alles auswählen

FO_READ
und da gibts dann den 32er. Offensichtlich haben die das bei memoread() so von mir übernommen. :D

Resümee: Der Code von Otto funktioniert so nicht, oder man schließt fürs memoread die aktuell geöffnete Dbf und öffnet sie dann gleich wieder. Oder Otto hat ein anderes memoread als wir?
es grüßt

Werner

<when the music is over, turn off the lights!>
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: Suche in großen Datenbeständen

Beitrag von brandelh »

Ach wenn es bei mir noch nie zu Problemen gekommen ist, empfiehlt Alaska memoread() nur für reine Texte zu nutzen (angeblich Codepageanpassungen).
Binärdaten (dazu zählen auch DBF-Dateien) soll man mit Funktionen wie File2Str() (siehe oben oder aus den XbToolsIII) oder direkt über fopen() etc. einlesen.

So klappt das dann auch mit der offenen DBF ;-)
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

Servus Hubert,

danke, da stimme ich Dir 100%ig zu.
Außerdem hat man mit den low-level-Funktionen auch die Möglichkeit, mit großen, den virtuellen Speicher übersteigenden Dateien umzugehen. Für mich ist die fixe und schlaue Lösung von Otto eigentlich nicht zu gebrauchen, weil die Dateien - wie die Überschrift schon sagt - meist über dem Swap-Bereich liegen. Auch setzen viele noch 32bit-Systeme ein, da geht natürlich fast gar nichts.
es grüßt

Werner

<when the music is over, turn off the lights!>
Benutzeravatar
azzo
Rekursionen-Architekt
Rekursionen-Architekt
Beiträge: 483
Registriert: So, 28. Mär 2010 19:21
Danksagung erhalten: 11 Mal

Re: Suche in großen Datenbeständen

Beitrag von azzo »

Hallo Werner, hallo Hubert,
es tut mir leid, dass memoread() in xBase nicht so arbeitet, wie unter harbour/clipper. Ich bin davon ausgegangen, dass der Code kompatibel ist.
Mfg
Otto


MemoRead()
Reads an entire file from disk into memory.
Syntax
MemoRead( <cFileName> ) --> cString
Arguments
<cFileName>
This is a character string holding the name of the file to read. It must include path and file extension. If the path is omitted from <cFileName>, the file is searched in the current directory.
Return
The function returns the entire contents of file <cFileName> as a character string. If the file is not found, an empty string ("") is returned.
Description
MemoRead() provides the fastest way of reading the entire contents of a file from disk and assign it to a memory or field variable. The function searches a file only in the current directory, if <cFileName> is not a full qualified file name. The settings of SET PATH and SET DEFAULT are ignored.
The file is opened as read-only and in shared mode. If this fails due to another process having obtained exclusive access to the file, or if the file is not found, the return value is an empty string ("").
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: Suche in großen Datenbeständen

Beitrag von brandelh »

azzo hat geschrieben:Hallo Werner, hallo Hubert,
es tut mir leid, dass memoread() in xBase nicht so arbeitet, wie unter harbour/clipper. Ich bin davon ausgegangen, dass der Code kompatibel ist.
Mfg
Otto
Hallo Otto,

dir muss das gar nicht leid tun.

Schließlich versucht man hier zu helfen und ist kein bezahlter Supportmitarbeiter.
Dass du Harbour einsetzt, erklärt das unterschiedliche Verhalten, aber auch ich ging davon aus, dass memoread() readonly shared öffnet.
Das Beispiel zeigt es anders ... man lernt halt nie aus.

:D
Gruß
Hubert
Benutzeravatar
Werner_Bayern
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2121
Registriert: Sa, 30. Jan 2010 22:58
Wohnort: Niederbayern
Hat sich bedankt: 30 Mal
Danksagung erhalten: 72 Mal

Re: Suche in großen Datenbeständen

Beitrag von Werner_Bayern »

Servus Otto,

mir war nicht bewusst, dass Du von Harbour schreibst. Ich hab halt stundenlang rumgetestet und wie immer den Fehler bei mir gesucht, Zeit ist eh immer zu knapp, mit anderen Worten: Sorry, wollte Dich nicht diffamieren. :silent:
es grüßt

Werner

<when the music is over, turn off the lights!>
Antworten