Schlagwort-Archive: Bug

OLEDB/ADO: „Der Accessor ist kein Parameteraccessor“

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:

Laufzeitfehler (80040e4b): Der Accessor ist kein Parameteraccessor.

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 )
Desweiteren gibt es auch Beschreibungen von Szenarien mit der gleichen Fehlermeldung, wenn Datumsfelder mit Jahreszahlen < 100 übermittelt werden. Unter OLE ist das Minimum für Datumsangaben der 1.1.100 (siehe hier).

Weblinks

Advertisements

Security Fix verhindert Recovery

Im „Security Alert Advisory for CVE-2012-3132“ wird vor einer Bedrohung gewarnt, die wieder einmal von David Litchfield entdeckt wurde. Dabei kann mithilfe von Anführungszeichen in Objektnamen SQL-Code eingeschleust und mit SYS-Rechten ausgeführt werden, wenn man

  1. einen autorisierten Zugang zur DB hat,
  2. dieser User CREATE TABLE und CREATE PROCEDURE-Privilegien hat und
  3. dieser User DBMS_STATS ausführen darf.

Im Juli 2012 wurde ein Fix veröffentlicht, jedoch gibt es auch eine Empfehlung von Oracle, wie der Gefahr ohne Einspielung eines Patches zu begegnen ist. Diese Empfehlung hat jedoch Folgen für Recovery oder Klone einer derart behandelten DB:

Weiterlesen

GROUP BY und ORA-00979 in 10gR2 und 11gR2

Aus der Rubrik „heute dazugelernt“: Oracle erlaubt es, mindestens seit 9iR2 (frühere Versionen habe ich nicht getestet), mehr Spalten in einer SELECT-Liste anzugeben, als später in der GROUP BY-Klausel verwendet werden.

Für Aggregatfunktionen wie COUNT(), SUM(), etc. ist das ja klar, es geht darüberhinaus aber auch mit

  1. Konstanten
  2. Ausdrücken, die für jede Zeile einer Gruppe denselben Wert liefern (also z.B. von einer der Spalten im GROUP BY abgeleitet sind).

Weiterlesen

Bug: Basic Table Compression und lang laufende UPDATEs

Im Rahmen eines Projektes, in dem Basic Table Compression eingesetzt wird, bin ich offensichtlich in einen Bug gelaufen. Umgebung:

  • Oracle 11.2.0.3.0, Enterprise Edition
  • Solaris 10

Ziel war die Maskierung von Daten auf einer großen, partitionierten Tabelle, die mit dem Attribut COMPRESS erstellt wurde. Gegenüber einer unkomprimierten Version waren die Laufzeiten für ein Update allerdings zehn- bis zwanzigmal länger und mit 100% CPU-Last während der vollen Laufzeit verbunden.

Hier ein Testfall, der auch ohne Partitionierung (und im Prinzip auch ohne die hier verwendeten Regular Expressions) auskommt: Weiterlesen

Anmerkungen zu INSERT ALL

Seit Oracle 9i gibt es die Option des sogenannten „Multi-Table Insert“, mit dem die bekannte INSERT … SELECT … – Syntax so erweitert wurde, daß die Ergebnisse aus dem SELECT auf mehrere Tabellen verteilt werden können. Ein paar Beispiele stehen in der Oracle-Doku.

INSERT ALL und Sequences

Nicht ganz intuitiv ist die Verwendung von Sequences: Soll z.B. in einer Master-Detail-Beziehung eine ID aus einer Sequence mehrfach verwendet werden, so kommt nicht CURRVAL zum Einsatz, sondern es muß überall NEXTVAL verwendet werden:

INSERT ALL
      INTO master_tab ( id, kunde_nr, ... )
    VALUES ( master_seq.NEXTVAL, ... )
      INTO detail_tab ( master_id, detail_nr, ... )
    VALUES ( master_seq.NEXTVAL, 1, ... )
    SELECT kunde_nr
      FROM tmp_aktive_kunden;

Bugs mit Master-Detail-Tabellen

Wenn man das obige Beispiel einmal ausprobiert, kann es durchaus vorkommen, daß es abbricht, wenn eine Fremdschlüsselbeziehung zwischen den Tabellen vorliegt.

ORA-02291: integrity constraint violated - parent key not found

Es handelt sich dabei um den seit 2003 bis heute noch nicht behobenen Bug 2891576. Dieser Bug lässt sich umgehen, indem das vorhandene Constraint entweder deaktiviert oder mit Deferred Constraints gearbeitet wird.

Allerdings gibt es auch beim Workaround einen Wermutstropfen: In einem Szenario mit zwei Tabellen von je etwa 2 Millionen Datensätzen und einem Insert von je 400000 Datensätzen kam es auf einem meiner Testsysteme (10.2.0.3, HP-UX 11.31 Itanium) zu sehr langen Laufzeiten, wenn Deferred Constraints verwendet wurden. Ohne Constraint war das Statement in Sekunden durch. Eine Klärung durch Oracle steht noch aus, ich werde den Artikel dann ergänzen.

Edit vom 21.1.2010:
Für den o.g. „Wermutstropfen“ ist bei Oracle inzwischen der Bug #9169330 erfasst, der momentan aber nicht öffentlich einsehbar ist. Auf jeden Fall arbeitet Oracles Entwicklungsteam daran.

Weblinks