Direkt zum Hauptbereich

Wie man Access 2010 (Oracle-) Transaktionen beibringt

Microsoft Access ist ein vielgenutztes Produkt in zahlreichen Unternehmen aller Branchen. Dies liegt darin begründet, dass das Microsoft-Office-Paket weit verbreitet ist, und die ,Access-Lösung' somit überall vorhanden.
Leider hat diese Lösung auch Nachteile. Diese machen sich bemerkbar, wenn mann ein Access-Frontend für eine Datenbankanbindung realisiert. Einer dieser Nachteile ist die fehlende Möglichkeit, Transaktionen zu realisieren oder auf Stored Procedures sowie Table-Functions zurückzugreifen.
Über die Access-Oberfläche allein ist dies auch so nicht möglich. Es gibt zwar einen SQL-Pass-Through, um DBMS-proprietäre SQL-Abfragen auszuführen, jedoch sind diese oftmals nur statisch möglich und müssen angepasst werden.

Visual Basic for Applications (kurz VBA) kann hier eine gewisse Abhilfe schaffen. So ist es  z. B. möglich, den Button-Steuerelementen eines Access-Formulars VBA-Makros (Subs) zuzuweisen, und diese beim Klicken auszuführen. Ereignisse wie dieses OnClick-Ereignis können jedoch nicht nur für das Klicken eines Buttons implementiert werden. Ferner existieren über ein Dutzend solcher Ereignisse, auf die VBA reagieren kann. Beispielsweise kann ein Ereignis behandelt werden, wenn das Formular geöffnet, aktiviert oder geschlossen wird.
Weiterhin ist es möglich, über die Access-Database-API auf den Workspace zuzugreifen und eine Transaktion zu starten, um später über einen Button eine dynamische Pass-Through-Abfrage abzusetzten und erst danach ein Commit oder Rollback durchzuführen. Es werden folgende Steuerelemente beötigt:

Typ:     Name:
Button   But_Commit
Button   But_Rollback

Für das Form_Open-Ereignis genügt bereits eine Zeile, um die Transaktion zu beginnen:
Private Sub Form_Open(Cancel As Integer)
 ' initialize a transaction
 DBEngine.BeginTrans
End Sub

Passend dazu muss man die Transaktion nun mit Commit in einem OnClick-Ereignis beenden:
Private Sub But_Commit_Click()
 ' commit transaction
 DBEngine.CommitTrans
End Sub

Oder mittels Rollback verwerfen:
Private Sub But_RollBack_Click()
 ' rollback the transaction
 DBEngine.Rollback
End Sub

Bis hier waren alles einfache und übersichtliche Einzeiler; etwas aufwendiger wird es nun, die Daten in die Datenbank einzufügen. Denn die normalen Access-Funktionen committen sofort, dies kann auch mit den vorherigen VBA-Statements nicht außer Kraft gesetzt werden. Stattdessen muss man nun Formular-Felder verwenden, die NICHT mit den Attributen einer Tabelle verknüpft sind. Sie müssen lediglich eindeutige Namen Besitzen:

Typ:     Name:
Button   But_Insert
Textfeld EdVorname
Textfeld EdNachname
Textfeld EdGeburt
Textfeld EdMember

Hinweis: Da hier mit einer Stored Procedure gearbeitet wird, werden zwei Datumswerte durch einen String im Format 'TT.MM.YYYY' übergeben (EdGeburt, EdMember). Der Code für den Button den Aufruf der Prozedur, die den Datensatz einfügt:

Private Sub But_Insert_Click()
 Dim ParamString As String
 Dim LSProc As QueryDef

 ' enable error handling
 On Error GoTo 0

 ' create parameters without parameter binding
 ParamString = "'" + Forms(thisForm).Controls("EdVorname").Value + "',"
 ParamString = ParamString + "'" + Forms(thisForm).Controls("EdNachname").Value + "',"
 ParamString = ParamString + "'" + Format(Forms(thisForm).Controls("EdGeburt").Value, "dd.mm.yyyy") + "',"
 ParamString = ParamString + "'" + Format(Forms(thisForm).Controls("EdMember").Value, "dd.mm.yyyy") + "'"

 ' create a querydef fpr global database var gDAODB
 Set LSProc = CurrentDb.CreateQueryDef("")

 'specify the connection manually
 LSProc.Connect = "ODBC;DSN=SLIGO_FH-TRIER"

 LSProc.SQL = "begin banking.insert_kunde(" + ParamString + "); end;"

 ' we don't expect any output
 LSProc.ReturnsRecords = False

 ' we ignore the timeout
 LSProc.ODBCTimeout = 0

 LSProc.Execute
End Sub

Wenn man nun das Formular öffnet, wird die Transaktion durch das Form_Open-Ereignis begonnen. Die Werte werden nun in die Textfelder eingefügt und ein Klick auf den Insert-Button führt für die lokale Oracle-Session ein Insert durch. Öffnet man nun eine zweite Session und schaut sich den Datenbestand an, so wird man keine Änderungen erkennen.
Nun klickt man den Button Cut_Commit. Eine zweite Abfrage der Daten über die zweite Session lässt erkennen, dass der Bestand sich nun geändert hat - die Transaktion war erfolgreich.

Als Verbesserung arbeite ich noch an Prepared Statements. Allerdings endeten bisher alle Versuche in Fehlern.

Kommentare

Beliebte Posts aus diesem Blog

Pi And More 11 - QMC5883 Magnetic Field Sensor Class

A little aside from the analytical topics of this blog, I also was occupied with a little ubiquitous computing project. It was about machine learning with a magnetic field sensor, the QMC5883. In the Arduino module GY-271, usually the chip HMC5883 is equipped. Unfortunately, in cheap modules from china, another chip is used: the QMC5883. And, as a matter of course, the software library used for the HMC5883 does not work with the QMC version, because the I2C adress and the usage is a little bit different. Another problem to me was, that I  didn't find any proper working source codes for that little magnetic field device, and so I had to debug a source code I found for Arduino at Github  (thanks to dthain ). Unfortunately it didn't work properly at this time, and to change it for the Raspberry Pi into Python. Below you can find the "driver" module for the GY-271 with the QMC5883 chip. Sorry for the bad documentation, but at least it will work on a Raspberry Pi 3.

How to use TOracleConnection under Lazarus for Win64

Lazarus Programmers have had no possibility to use TOracleConnection under 64 Bit Windows and Lazarus for years. Even if you tried to use the TOracleConnection with a correctly configured Oracle 11g client, you were not able to connect to the Oracle Database. The error message was always: ORA-12154: TNS:could not resolve the connect identifier specified Today I found a simple workaround to fix this problem. It seems like the OCI.DLL from Oracle Client 11g2 is buggy. All my attempts to find identify the error ended here. I could exclude problems with the TNS systems in Oracle - or the Free Pascal file oracleconnection.pp though the error messages suggestes those problems. After investigating the function calls with Process Monitor (Procmon) I found out, that even the file TNSNAMES.ORA was found and read correctly by the Lazarus Test applictaion. So trouble with files not found or wrong Registry keys could also be eliminated. Finally I installed the Oracle Instant Client 12.1c - aft

Lazarus IDE and TOracleConnection - A How-To

Free programming IDEs are a great benefit for everybody who's interested in Programming and for little but ambitious companies. One of these free IDEs is the Lazarus IDE . It's a "clone" of the Delphi IDE by Embarcadero (originally by Borland). But actually Lazarus is much more than a clone: Using the Free Pascal-Compiler , it was platform-independent and cross-compiling since it was started. I am using Lazarus very often - especially for building GUIs easily because Java is still Stone-Age when a GUI is required (though there is a couple of GUI-building tools - they all are much less performant than Delphi / Lazarus). In defiance of all benefits of Lazarus there still is one Problem. Not all Components are designed for use on a 64 bit systems. Considering that 64 bit CPUs are common in ordinary PCs since at least 2008, this is very anpleasant. One of the components which will not be available on 64 bit installations is the TOracleConnection of Lazarus' SQLDB