Fehler bei INDEX ON ...

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

Moderator: Moderatoren

Antworten
KlausL
UDF-Programmierer
UDF-Programmierer
Beiträge: 54
Registriert: Fr, 23. Okt 2009 11:38

Fehler bei INDEX ON ...

Beitrag von KlausL »

Hallo,

wer kann mir folgendes Programmverhalten erklären? Für Eure Bemühungen schon jetzt vielen Dank im Voraus!

Umgebung:
Xbase++: 1.90.331
Windows: XP Professional Service Pack 3


Viele Grüße,

Klaus



Procedure Verkaufsstatistik(cFilter)

local cNtx := TempFile(pblc_sTemp, "ntx")

field deb_nr, art_nr

Select vkstaXX
DbSetRelation( "debsta02", {|| vkstaXX->deb_nr} )
Index on deb_nr + art_nr to (cNtx) for &cFilter



Wenn die Länge von cFilter einen bestimmten Wert nicht überschreitet, funktioniert das Programm, ab dieser Länge erhalte ich dann allerdings folgenden Laufzeitfehler:

Error BASE/8999
Description: Länge des Datenbankfeldes wurde überschritten
Operation: OrdCreate()

Beispiel Kein Laufzeitfehler, funktioniert:

cFilter = 'deb_nr >= "100002" .and. deb_nr <= "309719" .and. art_nr >= " 1" .and. art_nr <= "ANL" .and. vt1_nr >= 0 .and. vt1_nr <= 99 .and. debsta02->deb_gr >= "01" .and. rg_dat >= ctod("01.01.2012") .and. rg_dat <= ctod("31.12.2012")'

Beispiel für Laufzeitfehler:

cFilter = 'deb_nr >= "100002" .and. deb_nr <= "309719" .and. art_nr >= " 1" .and. art_nr <= "ANL" .and. vt1_nr >= 0 .and. vt1_nr <= 99 .and. debsta02->deb_gr >= "01" .and. debsta02->deb_gr <= "03" .and. rg_dat >= ctod("01.01.2012") .and. rg_dat <= ctod("31.12.2012")'
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2827
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Fehler bei INDEX ON ...

Beitrag von georg »

Hallo,


gemäss Handbuch beträgt bei der NTX-DBE die maximale Länge der FOR Expression 255 Zeichen. Ist Dein Filter länger, knallt es.

Code: Alles auswählen

If Len(cFilter) > 255
   ConfirmBox(, "Filterausdruck ist zu komplex", "Fehler", XBPMB_OK, XBPMB_INFORMATION)
   Retu(.F.)
EndIf
Oder so ähnlich.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
KlausL
UDF-Programmierer
UDF-Programmierer
Beiträge: 54
Registriert: Fr, 23. Okt 2009 11:38

Re: Fehler bei INDEX ON ...

Beitrag von KlausL »

Hallo Georg,

klar, ist einleuchtend.

Nochmals vielen Dank, muß ich mir ein anderes Vorgehen überlegen (letztendlich ein Performance-Problem, da zu filternde Verkaufsstatistik i. d. R. ca. eine knappe Mio. Sätze enthält).

Viele Grüße,

Klaus
georg
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 2827
Registriert: Fr, 08. Feb 2008 21:29
Hat sich bedankt: 96 Mal
Danksagung erhalten: 13 Mal

Re: Fehler bei INDEX ON ...

Beitrag von georg »

Hallo, Klaus -


prüfe doch anhand der Felder und der definierte Indexe, ob Du nicht einen Sub-Index bilden kannst. Eventuell lässt sich dadurch die Anzahl der Sätze eingrenzen.


Gruss,

Georg
Liebe Grüsse aus der Eifel,

Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
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: Fehler bei INDEX ON ...

Beitrag von Jan »

Du könntest auch mal schauen, ob ein Scope auf deb_nr helfen könnte, mit Angaben von SCOPE_TOP und SCOPE_BOTTOM. Auf den Rest der Bedingungen kannst Du dann immer noch einen Filter setzen. Der geht dann aber schon nur noch auf den eingegrenzten Debitoren-Bereich, und ist dadurch wesentlich schneller.

Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Paul Brem
Rookie
Rookie
Beiträge: 18
Registriert: Di, 11. Apr 2006 8:30
Wohnort: CH-8707 Uetikon

Re: Fehler bei INDEX ON ...

Beitrag von Paul Brem »

Verpack doch den Filterbegriff in eine Funktion, dann hast du im Index-Filter einen kurzen Begriff.
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Fehler bei INDEX ON ...

Beitrag von Herbert »

Jan hat geschrieben:Du könntest auch mal schauen, ob ein Scope auf deb_nr helfen könnte, mit Angaben von SCOPE_TOP und SCOPE_BOTTOM. Auf den Rest der Bedingungen kannst Du dann immer noch einen Filter setzen. Der geht dann aber schon nur noch auf den eingegrenzten Debitoren-Bereich, und ist dadurch wesentlich schneller.
Jan
Genau!
Du hast cFilter stets mit einer Eingrenzung des Index-Schlüssels (Teil deb-nr) mit definiert. Heisst, den Index ausschliesslich ohne die For-Bedingung generieren. Erst anschliessend weiter eingrenzen. Wobei je nach Arbeitsablauf mit den gefundenen Sätzen auch eine einfache IF-Klausel innerhalb des DO WHILE ebenso genügen könnte.
Grüsse Herbert
Immer in Bewegung...
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: Fehler bei INDEX ON ...

Beitrag von UliTs »

Ich gehe davon aus, dass Du die Tabellen mit NTX-Index mittels DBFNTX benutzt (also nicht z.B. mit dem ADS).
Dann ist meines Erachtens wie auch schon von Paul Brem erwähnt die einfachste und schnellste Lösung, im Filter eine Funktion zu benutzen!

Code: Alles auswählen

....
UTsDbSetFilter( "Filter1()" )               // Filter setzen
....

FUNCTION Filter1()
LOCAL lResult
lResult := deb_nr >= "100002" .and. deb_nr <= "309719" .and. art_nr >= " 1" .and. +;
           art_nr <= "ANL" .and. vt1_nr >= 0 .and. vt1_nr <= 99 .and. debsta02->deb_gr >= "01" .and. +;
           rg_dat >= ctod("01.01.2012") .and. rg_dat <= ctod("31.12.2012")
RETURN( lResult )

FUNCTION UTsDbSetFilter( cFilter ) // Im Gegensatz zu DbSetFilter() wird Filterbedingung nur als String
LOCAL cOldFilter:=DbFilter()       // uebergeben, "" akzeptiert und der alte Filter zurueckgegeben.
LOCAL cbFilter,bFilter
  IF valType(cFilter)=="C"
    IF empty( cFilter )
      DbClearFilter()
    ELSE
      cbFilter := "{||"+cFilter+"}"
      bFilter  := &cbFilter
      DbSetFilter( bFilter,cFilter )
    ENDIF
  ENDIF
RETURN( cOldFilter )
Schneller ist es vor allem, weil bei der Berechnung des macro-Operators zur Laufzeit nur noch der Aufruf der Funktion Filter1() interpretiert werden muß :-) .

Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Benutzeravatar
Herbert
Der Entwickler von "Deep Thought"
Der Entwickler von "Deep Thought"
Beiträge: 1991
Registriert: Do, 14. Aug 2008 0:22
Wohnort: Gmunden am Traunsee, Österreich
Danksagung erhalten: 3 Mal
Kontaktdaten:

Re: Fehler bei INDEX ON ...

Beitrag von Herbert »

Sehr komplex.
Unter SQL entsteht durch eine solche Auswahl eine neue Tabelle.
Entspricht - wenn schon - dem Einlesen der betreffenden Sätze in ein Array. Filter dürfen nirgends mehr vorkommen. Auch, weil bereits hier im Forum viel beschrieben, dies eine extrem langsame Funktion ist. Zudem ist der Filter ein Relikt aus alten Clipper-Tagen mit Datenmengen < 1000 Sätzen.
Grüsse Herbert
Immer in Bewegung...
Benutzeravatar
Bertram Hansen
Foren-Moderator
Foren-Moderator
Beiträge: 1015
Registriert: Di, 27. Sep 2005 8:55
Wohnort: 51379 Leverkusen
Hat sich bedankt: 28 Mal
Danksagung erhalten: 20 Mal
Kontaktdaten:

Re: Fehler bei INDEX ON ...

Beitrag von Bertram Hansen »

Alternative und schnelle Lösung ohne große Programmveränderung ---> einige Leerzeichen in dem Ausdruck entfernen
:wave:
Gruß Bertram
http://www.tobax.de
Mitglied der XUG Cologne
Mitglied der XUG Osnabrück
Beisitzer des Deutschsprachige Xbase-Entwickler e.V.

Solange Kakaobohnen an Bäumen wachsen ist Schokolade Obst!
KlausL
UDF-Programmierer
UDF-Programmierer
Beiträge: 54
Registriert: Fr, 23. Okt 2009 11:38

Re: Fehler bei INDEX ON ...

Beitrag von KlausL »

Hallo,

ich erzeuge meine Auswertung jetzt mittels SCOPE und dann einem DbSetFilter(); da ich für den Anwender nur noch eine max. Anzahl von Filterkriterien zulasse, ist das Zeitverhalten ganz ok.

Für Eure Vorschläge und Beispiele nochmals vielen Dank!

Klaus
Antworten