Probleme mit Datentyp Double vermeiden

Level 7 für dBASE-Datenbanken, das Sie in der BDE-Konfiguration einstellen können, bietet auch den Datentyp Double. Dieser numerische Datentyp mit fixen 8 Bytes wird von einigen dBASE-Befehlen leider falsch ausgewertet. Nehmen wir an, eine dBASE-Tabelle hat ein Feld namens doublefeld vom Datentyp Double. Die Tabelle enthält einige dutzend Datensätze mit unterschiedlichen Werten im Feld doublefeld. Selbst wenn alle Datensätze im Feld doublefeldWerte grösser 1 enthalten, liefern die Befehle

count all for doublefeld > 0
count all for doublefeld > 0.1
count all for doublefeld > 1

möglicherweise völlig unterschiedliche Ergebnisse! Bei der Abfrage doublefeld > 0 ist das Ergebnis oft 0, und je nach Konstellation bekommen Sie auch bei > 0.1 und >1 verschiedene Ergebnisse. Und das, wo doch alle drei Abfragen dasselbe Ergebnis liefern sollten, wenn alle Datensätze in doublefeld einen Wert grösser 1 enthalten. Erschreckend aber wahr.

Dasselbe fragwürdige Verhalten gilt für Befehle wie

replace all textfeld with “xyz” for doublefeld > 0

der möglicherweise keine einzige Ersetzung des Felds textfeld durchführen wird, ganz gleich wieviele Datensätze mit der Bedingung doublefeld > 0 es tatsächlich gibt.

Das Problem kann auf diverse andere dBASE-Befehle zutreffen, die direkt mit Tabellenfeldern arbeiten, und es ist i.d.R. auch egal, ob Sie die “alten” Zugriffsmethoden mit use … oder die “neuen” mit query und rowset verwenden. Die Ursache liegt vermutlich irgendwo in der BDE (Borland Database Engine) begraben, welche ja schon recht betagt ist und bei Einführung des neuen Level 7 für dBASE-Tabellen evtl. nicht sorgfältig genug angepasst wurde.

Ich konnte das Problem mit allen Level 7 Versionen von dBASE reproduzieren, angefangen mit dBASE 2000 aus dem Jahr 2001 bis hin zu dBASE 8 von 2013. Das verwundert jedoch nicht wirklich, denn die BDE ist ja in all diesen Versionen im Kern dieselbe. Das Problem ist auf Level 7 Tabellen und dort auf den Datentyp Double beschränkt. Bei Level 5 Tabellen gibt es diesen Datentyp sowieso nicht, und auch bei Level 7 können Sie sich behelfen.

Lösung 1 (nur unter Vorbehalt):
Wandeln Sie Double-Felder vor dem Zugriff in “normale” numerische Werte um, z. B. mit int()oder abs(). Allerdings geht dann je nach Umwandlung der Nachkomma-Anteil verloren.

count all for int(doublefeld) > 0
count all for abs(doublefeld) > 0

liefert meist die korrekten Ergebnisse, zumindest wenn es auf Kommastellen nicht ankommt.

Lösung 2 (die sichere Variante):
Verzichten Sie auf die Verwendung des Datentyps Double. Verwenden Sie stattdessen den altbekannten Datentyp Numerisch und geben Sie die Anzahl der benötigten Vor- und Nachkommastellen im Tabellen-Designer bei jedem Feld an. Bestehende Double-Felder können problemlos in numerische Felder geändert werden, die Daten bleiben erhalten.

Ich rate zu Lösung 2, denn es ist erstens nicht gesichert, dass Lösung 1 wirklich in allen Fällen richtig funktioniert, und zweitens: wenn schon so simple Befehle wie count und replace Probleme mit dem Datentyp Double haben, was passiert dann erst bei etwas komplexeren Tabellenoperationen? Da denkt man besser garnicht erst drüber nach, sondern entsorgt konsequent alle Double-Felder aus dBASE-Tabellen. Sicher ist sicher.

(Stand dieser Info: 2014)