MS Acces als Frontend auf Oracle Datenbak Schreibkonflikt

26/11/2007 - 15:39 von Jens Törber | Report spam
Hallo zusammen,

wir versuchen eine MS Access 2003-Datenbank auf Oracle zu migrieren. Wir
erhalten gelegentlich Schreibkonflikte, weil sich angeblich ein Datensatz
geàndert hat. Bei meinen Tests bin ich jedoch allein auf der Datenbank, so
daß dies nicht sein kann.

Meine Recherchen haben ergeben, daß man bei der Migration beim Typ-Mapping
aufpassen muss sowie default's bei ehemals ja/nein-Spalten.

In den Update-Statements ist immer ibn der WHERE-Klausel die ganze Liste an
Spalten enthalten, die es in der darunterliegenden Tabelle gibt, um zu
checken, ob sich der Datensatz in der Zwischenzeit geàndert hat.

Das brauchen wir in der Form eigentlich gar nicht. Dr letzte gewinnt würde
uns reichen.

Bei Gleitpunktzahlen und gewissen nullable-Spalten sollen hier Rundungs-
oder Wertefehler auftreten, so daß das Update schief geht.

Abhilfe wàre eine dem MS SQL-Server àhnliche timestamp-Spalte.

Ab Oracle 10g gibt es eine ora_rowscn, die sofern create table mit der
Zusatzklausel ROWDEPENDENCIES ausgeführt wurde, eine Zeilenversionierung
durchführt.

Eine direkt Verknüpfung auf diese Tabelle ergab jedoch dieselben
Update-Statements, ein Trick mit Verknüpfung auf einen View mit
create or replace view as select p.*, scn_to_timestamp(ora_rowscn) from
persontest p
war ebenfalls erfolglos.

Anbei unser create table:

CREATE TABLE PERSONtest
(
PERSON_ID NUMBER(11),
ADRESSE_ID NUMBER(11) NOT NULL,
PARENT_ADRNR VARCHAR2(255 BYTE),
ADRESSNUMMER VARCHAR2(255 BYTE),
ABTEILUNG VARCHAR2(255 BYTE),
POTENTIALNUMMER_INT NUMBER(11) DEFAULT 0,
FACHRICHTUNG VARCHAR2(255 BYTE),
FACHBEREICH_TEXT VARCHAR2(50 BYTE),
TITEL_DR VARCHAR2(255 BYTE),
VORNAME VARCHAR2(255 BYTE),
NACHNAME VARCHAR2(255 BYTE),
TELEFON VARCHAR2(50 BYTE),
APOTHEKEN_ID VARCHAR2(255 BYTE),
EMAILADDRESS VARCHAR2(50 BYTE),
HERKUNFT VARCHAR2(50 BYTE),
CHEFAPOTHEKER NUMBER(5) DEFAULT 0
NOT NULL,
ANREDE VARCHAR2(50 BYTE),
POSITION VARCHAR2(50 BYTE),
AKADEMISCHER_GRAD VARCHAR2(50 BYTE),
BRIEFANSCHRIFT VARCHAR2(100 BYTE),
BRIEFANREDE VARCHAR2(100 BYTE),
MAFOCUBIZIN_ID NUMBER(11),
EMPFANG VARCHAR2(50 BYTE),
SEKRETAERIN VARCHAR2(50 BYTE),
PTA VARCHAR2(50 BYTE),
FAX VARCHAR2(50 BYTE),
GESPERRT NUMBER(5) DEFAULT 0
NOT NULL,
AUSBLENDEN NUMBER(5) DEFAULT 0
NOT NULL,
FUNKTION VARCHAR2(50 BYTE),
WV_CUBIZIN DATE,
NOTIZ VARCHAR2(4000 BYTE),
CUBIZIN_INTERESSE NUMBER(5) DEFAULT 0
NOT NULL,
WV_CUBIZIN_ZEIT NUMBER(11) DEFAULT 0,
INFOMATERIAL NUMBER(5) DEFAULT 0
NOT NULL,
STRASSE VARCHAR2(50 BYTE),
PLZ VARCHAR2(50 BYTE),
ORT VARCHAR2(50 BYTE),
POSTFACH VARCHAR2(50 BYTE),
HERKUNFTNOVARTISAPOTHEKER NUMBER(5) DEFAULT 0
NOT NULL,
PRIM_STELLUNG_BEI_INST VARCHAR2(50 BYTE),
TITEL_PRIMAER VARCHAR2(50 BYTE),
PERSONENSTATUS_SCHL VARCHAR2(50 BYTE),
PERSONENSTATUS_TEXT VARCHAR2(50 BYTE),
STELLUNG_SCHL VARCHAR2(50 BYTE),
STELLUNG_TEXT VARCHAR2(50 BYTE),
CCUSER_ID NUMBER(11),
ADRESSNUMMER_SAFE VARCHAR2(50 BYTE),
PARENT_ADRNR_SAFE VARCHAR2(50 BYTE),
ADRESSE_ID_SAFE NUMBER(11),
DELADR NUMBER(5) DEFAULT 0
NOT NULL,
DELPERS NUMBER(5) DEFAULT 0
NOT NULL,
AUTODELCHEFAPOTHEKER NUMBER(5) DEFAULT 0
NOT NULL,
CC_TITEL VARCHAR2(50 BYTE),
CC_VORNAME VARCHAR2(50 BYTE),
CC_NAME VARCHAR2(50 BYTE),
CC_TELEFON VARCHAR2(50 BYTE),
CC_AN VARCHAR2(4000 BYTE),
CC_AO VARCHAR2(4000 BYTE),
CC_AP VARCHAR2(4000 BYTE),
ANGERUFEN NUMBER(5) DEFAULT 0
NOT NULL,
HERKUNFT_CC NUMBER(5) DEFAULT 0
NOT NULL,
CC_CCUSER_ID NUMBER(11),
CC_ADRTELEFON VARCHAR2(50 BYTE),
CC_ANREDE VARCHAR2(200 BYTE),
DOPPELT NUMBER(5) DEFAULT 0
NOT NULL,
HERKUNFT_CALLCENTER VARCHAR2(50 BYTE),
TELEFON2 VARCHAR2(50 BYTE),
PERSON_BY_CC NUMBER(5) DEFAULT 1
NOT NULL,
ARZTMAILINGRESPONSE NUMBER(5) DEFAULT 0
NOT NULL,
ARZTMAILINGCUBINFO NUMBER(5) DEFAULT 0
NOT NULL,
APOTHEKERMAILINGRESPONSE NUMBER(5) DEFAULT 0
NOT NULL,
APOTHEKERCUBINFO NUMBER(5) DEFAULT 0
NOT NULL,
APOTHEKERADBESUCH NUMBER(5) DEFAULT 0
NOT NULL,
BOOKMARKED NUMBER(5) DEFAULT 0
NOT NULL,
UNTERABTEILUNG_ID NUMBER(11),
BEHANDLUNGSSCHWERPUNKTKURZ VARCHAR2(50 BYTE),
INFOMATERIALERHALTEN NUMBER(5) DEFAULT 0
NOT NULL,
INFOMATERIALINPROGRESS NUMBER(5) DEFAULT 0
NOT NULL,
NICHTANRUFEN NUMBER(5) DEFAULT 0
NOT NULL,
KONGRESSNAME VARCHAR2(50 BYTE),
KONGRESSDATUM DATE,
LASTTRICK NUMBER(5) DEFAULT 0
NOT NULL,
MAILINGTYPE VARCHAR2(50 BYTE),
MAINTHERAPIEGEBIET_SCHL VARCHAR2(50 BYTE),
BEHANDLUNGSSCHWERPUNKTKURZ2 VARCHAR2(50 BYTE),
CUBIZIN_AD NUMBER(11),
HERKUNFTTHERAPIEGEBIET NUMBER(5) DEFAULT 0
NOT NULL,
PERSONENGRUPPE VARCHAR2(50 BYTE),
IGNOREPERSON NUMBER(5) DEFAULT 0
NOT NULL,
INFOMATERIALAUSGANG DATE,
MAILINGTYPENEU VARCHAR2(50 BYTE),
REGIONALLEITEREMPFEHLUNG NUMBER(5) DEFAULT 0
NOT NULL,
REGIONALLEITERBEMERKUNG VARCHAR2(4000 BYTE),
LINIE_500_BESUCH NUMBER(5) DEFAULT 0
NOT NULL,
LINIE_600_BESUCH NUMBER(5) DEFAULT 0
NOT NULL,
LINIE_1600_BESUCH NUMBER(5) DEFAULT 0
NOT NULL,
LINIE_5800_BESUCH NUMBER(5) DEFAULT 0
NOT NULL,
HERKUNFT_CUBIZIN_AD NUMBER(5) DEFAULT 0
NOT NULL,
HERKUNFTMAILRESPONDER NUMBER(5) DEFAULT 0
NOT NULL,
MAILRESPONDER_ID NUMBER(11),
HERKUNFTRLEMPFEHLUNG NUMBER(5) DEFAULT 0
NOT NULL,
RLEMPFEHLUNG_ID NUMBER(11),
KONGRESSMAILINGRESPONSE NUMBER(5) DEFAULT 0
NOT NULL,
KONGRESSCUBINFO NUMBER(5) DEFAULT 0
NOT NULL,
KONGRESSADBESUCH NUMBER(5) DEFAULT 0
NOT NULL,
REGIONALLEITER VARCHAR2(50 BYTE),
REGIONALLEITERBEZIRK VARCHAR2(50 BYTE),
ADBESUCH NUMBER(5) DEFAULT 0
NOT NULL,
INFOPEREMAIL NUMBER(5) DEFAULT 0
NOT NULL,
SPERRGRUND_ID NUMBER(11),
BEHANDLUNGSSCHWERPUNKT1_ID NUMBER(11),
BEHANDLUNGSSCHWERPUNKT2_ID NUMBER(11),
CONSTRAINT PK_PERSONTEST
PRIMARY KEY
(PERSON_ID)
) ROWDEPENDENCIES;

Das Debuggen erschwert sich, da das Phànomen abhàngig vom OS und dem
Datensatz sporadisch aber regelmàßig auftritt.

Btw.
Die Oracle Migration Workbench, die im freien Oracle SQL Developer enthalten
ist, und uns als Vergleich unserer manuellen Migration dienen sollte, ist bis
jetzt nicht zum Ende der Migration durchgelaufen und scheint zu hàngen.

Jede Hilfe oder andere Workarounds willkommen.
 

Lesen sie die antworten

#1 Stefan Hoffmann
26/11/2007 - 16:20 | Warnen spam
hallo Jens,

Welchen Treiber benutzt ihr?

Jens Törber schrieb:
[..] Das brauchen wir in der Form eigentlich gar nicht. Dr letzte gewinnt würde
uns reichen.


Da ist mir nichts bekannt, daß man daran etwas drehen kann. Die Idee
dahinter lautet, daß Access keine Daten àndert, welche schon auf dem
Server geàndert worden sind, die aber der àndernde Nutzer (Access) noch
nicht gesehen hat.

Bei Gleitpunktzahlen und gewissen nullable-Spalten sollen hier Rundungs-
oder Wertefehler auftreten, so daß das Update schief geht.


Das UPDATE sollte immer gehen, lediglich der nachfolgende SELECT schlàgt
fehl aufgrund von den Rundungsfehlern. Diese treten nur in Spalten mit
unpràzisen Werten auf. Im speziellen ist das normalerweise FLOAT. Die
von dir verwendenten NUMBER(n, 0) stellen kein Problem dar.

Nullable Spalten oder DEFAULT-Werte spielen hier eigentlich keine Rolle.

Abhilfe wàre eine dem MS SQL-Server àhnliche timestamp-Spalte.


Die TIMESTAMP-Spalte wird von Access/Jet und dem Treiber speziell
behandelt. Das gibt es bisher nur für den SQL Server.

Eine direkt Verknüpfung auf diese Tabelle ergab jedoch dieselben
Update-Statements, ein Trick mit Verknüpfung auf einen View mit
create or replace view as select p.*, scn_to_timestamp(ora_rowscn) from
persontest p
war ebenfalls erfolglos.


Wie gesagt, das ist eine spezielle Geschichte.

Desweiteren fàllt mir am Skript nichts besonders auf, außer das soviele
Spalten in einer Tabelle selten richtig sind (Normalisierung).



mfG

Access-FAQ http://www.donkarl.com/
KnowHow.mdb http://www.freeaccess.de
Newbie-Info http://www.doerbandt.de/Access/Newbie.htm

Ähnliche fragen