Beim Zugriff aus MS Access heraus auf eine Oracle-Datenbank (11.2) kam es zu der folgenden Fehlermeldung, deren Ursache und Beseitigung ich hier kurz beschreiben möchte, da bislang kaum ein kurz zusammengefasster Artikel dazu im Netz zu finden ist:
Bei der Untersuchung der View, auf die zugegriffen wurde, fiel mir folgender Code auf:
(NVL(b.marktwertfondswhg, 0) - NVL(b.einstandswertfondswhg, 0)) / NVL(k.fondsvermoegen, 0)
Mal abgesehen davon, daß hier eine Division durch Null möglich wäre (nein, die View stammt nicht von mir…), war dies die einzige Spalte, in der ein Quotient gebildet wurde. Es lag also der Verdacht nahe, daß es sich um ein Problem mit inkompatiblen Datentypen handeln könnte.
Und in der Tat sollte es sich herausstellen, daß ADO maximal 28 Dezimalstellen unterstützt, wohingegen Oracles NUMBER-Datentyp bis zu 35 Dezimalstellen bietet. Seit Version 10.2 des „Oracle Provider for OLE DB“ stellt dieser Fließkommazahlen nicht mehr als Zeichenkette sondern eben als Zahl bereit, was also ab dem Einsatz dieser Version zu dem Problem führen kann.
Abhilfe schafft der Einsatz der Rundungsfunktion ROUND(). Der problematische Code von oben funktioniert dann problemlos mit folgender Umstellung:
ROUND((NVL(b.marktwertfondswhg, 0) - NVL(b.einstandswertfondswhg, 0)) / NVL(k.fondsvermoegen, 0), 28 )
Weblinks
- Retrieving a Number Greater than 28 Digits Using the Oracle Provider for OLE DB in an ADO Application Fails With: DB_E_BADACCESSORTYPE or „80040e4b Accessor is not a parameter accessor“ [ID 1470490.1]
- Oracle OLE DB Provider throws 80040e4b – Accessor Is Not a Parameter Accessor
- Microsoft Knowledge Base: „ADO unterstützt keine Decimal-Zahlen mit Genauigkeit mit mehr als 28“
- Diskussion des Datumsproblems im Delphi-Praxis-Forum