Fehler bei INDEX ON ...
Moderator: Moderatoren
Fehler bei INDEX ON ...
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")'
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")'
-
- 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 ...
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.
Oder so ähnlich.
Gruss,
Georg
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
Gruss,
Georg
Liebe Grüsse aus der Eifel,
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
Re: Fehler bei INDEX ON ...
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
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
-
- 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 ...
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
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.
Georg S. Lorrig
Redakteur der Wiki des Deutschprachigen Xbase-Entwickler e.V.
- Jan
- 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 ...
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
Jan
Mitglied der XUG Osnabrück
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Mitglied der XUG Berlin/Brandenburg
Mitglied des Deutschsprachige Xbase-Entwickler e. V.
Re: Fehler bei INDEX ON ...
Verpack doch den Filterbegriff in eine Funktion, dann hast du im Index-Filter einen kurzen Begriff.
- Herbert
- 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 ...
Genau!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
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...
Immer in Bewegung...
-
- 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 ...
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!
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
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 zurueckgegeben.
LOCAL cbFilter,bFilter
IF valType(cFilter)=="C"
IF empty( cFilter )
DbClearFilter()
ELSE
cbFilter := "{||"+cFilter+"}"
bFilter := &cbFilter
DbSetFilter( bFilter,cFilter )
ENDIF
ENDIF
RETURN( cOldFilter )
Uli
-------
Mitglied XuG Cologne
Mitglied XuG Osnabrück
Mitglied XuG Cologne
Mitglied XuG Osnabrück
- Herbert
- 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 ...
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.
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...
Immer in Bewegung...
- Bertram Hansen
- 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 ...
Alternative und schnelle Lösung ohne große Programmveränderung ---> einige Leerzeichen in dem Ausdruck entfernen
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!
Re: Fehler bei INDEX ON ...
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
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