{"id":55000677,"date":"2009-08-01T00:00:00","date_gmt":"2020-05-22T22:16:52","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=677"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/","title":{"rendered":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co."},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Haben Sie sich nicht auch schon immer gefragt, welche Zugriffstechnik am besten f&uuml;r den Zugriff auf Tabellen in aktiven Datenbanksystemen geeignet ist Falls Sie dies bereits mit ADODB- und DAO-Methoden getestet haben, wissen Sie vermutlich, dass keine Zugriffsmethode alle W&uuml;nsche eines Access-Programmierers erf&uuml;llt. Es bleibt also nichts anderes &uuml;brig, als die Einschr&auml;nkungen hinzunehmen oder unterschiedliche Methoden parallel einzusetzen.<\/b><\/p>\n<p>Im Beitrag <b>Anmeldung an SQL Server und Co.<\/b> wurde eine Methodensammlung zum Anmelden an aktive Datenbankmanagementsysteme (DBMS) vorgestellt (s. Shortlink 668). Diese Sammlung erweitern wir nun um eine Klassenstruktur zur Kapselung unterschiedlicher Verbindungstechniken. Voraussetzung zum Testen der nachfolgend vorgestellten Klassen ist eine Datenbank unter MySQL oder Microsoft SQL Server, die Sie &uuml;ber die Methoden des oben vorgestellten Beitrags mit der Frontend-Datenbank verkn&uuml;pfen. Ist dies erledigt, k&ouml;nnen Sie mit den Methoden und Eigenschaften sehr viel einfacher auf die Datenbank zugreifen als zuvor &#8211; und noch besser: Wenn Sie sich entscheiden, die Backend-Datenbank vom SQL Server nach MySQL zu &uuml;bertragen oder umgekehrt, brauchen Sie den Code f&uuml;r den Zugriff auf die Daten nicht zu &auml;ndern (das gilt wegen unterschiedlicher Dialekte jedoch nicht uneingeschr&auml;nkt f&uuml;r die enthaltenen SQL-Anweisungen). Bevor wir hinter die Kulissen schauen, hier ein paar Beispiele. Das erste betrifft die Dom&auml;nenfunktionen wie etwa <b>DCount<\/b>. Damit k&ouml;nnen Sie sich die Anzahl der Datens&auml;tze einer in der Datenbank enthaltenen oder verkn&uuml;pften Tabelle wie folgt ausgeben lassen:<\/p>\n<pre>Debug.Print DCount(\"*&euro;, \"tblArtikel&euro;)<\/pre>\n<p>Die nachfolgend vorgestellten Klassen erm&ouml;glichen erstens einen Zugriff auf die gleichen Informationen, allerdings auf Basis eines Recordsets. Handelt es sich um eine verkn&uuml;pfte Tabelle, verwenden Sie einfach die folgende Anweisung:<\/p>\n<pre>Debug.Print CurrentDBConnection.DAO.DCount(\"*&euro;, \"tblArtikel&euro;)<\/pre>\n<p>Vielleicht arbeiten Sie gar nicht mit einer Verkn&uuml;pfung, sondern m&ouml;chten per ADODB direkt auf die Tabelle des MySQL- oder SQL Servers zugreifen Dann funktioniert diese Variante:<\/p>\n<pre>Debug.Print CurrentDBConnection.ADODB.DCount(\"*&euro;, \"tblArtikel&euro;)<\/pre>\n<p>Die Klassen bieten noch eine Reihe weiterer Funktionen, beispielsweise um ein Recordset zu erzeugen. F&uuml;r eine verkn&uuml;pfte Tabelle sieht dies so aus:<\/p>\n<pre>Set rst = CurrentDBConnection.DAO.OpenRecordset(\"SELECT * FROM tblArtikel&euro;)<\/pre>\n<p>Ist die Tabelle nicht verkn&uuml;pft, hilft die ADODB-Variante weiter:<\/p>\n<pre>Set rst = CurrentDBConnection.ADODB.OpenRecordset(\"SELECT * FROM tblArtikel&euro;)<\/pre>\n<p>Sie k&ouml;nnen aber auch mit einem DAO-Recordset arbeiten, das via ODBC erzeugt wurde:<\/p>\n<pre>Set rst = CurrentDBConnection.ODBC.OpenRecordset(\"SELECT * FROM tblArtikel&euro;)<\/pre>\n<p>Es gibt noch einige weitere Funktionen, mit denen Sie etwa den Connectionstring der aktuell verwendeten Verbindung ausgeben k&ouml;nnen. Mehr dazu erfahren Sie weiter unten.<\/p>\n<p><b>Grundlagen<\/b><\/p>\n<p>F&uuml;r den Zugriff von einem Access-Frontend auf ein DBMS stehen unterschiedliche Verbindungstechniken zur Verf&uuml;gung:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Verkn&uuml;pfte Tabellen und Sichten (ODBC)<\/li>\n<li class=\"aufz-hlung\">Pass-Through-Abfragen (ODBC)<\/li>\n<li class=\"aufz-hlung\">ADO-Verbindung zur Datenbank (OLEDB)<\/li>\n<li class=\"aufz-hlung\">ODBCDirect (ODBC)<\/li>\n<li class=\"aufz-hlung\">DAO-Database-Instanz mit ODBC-Connectionstring (ODBC)<\/li>\n<\/ul>\n<p>Die folgenden Abschnitte stellen diese M&ouml;glichkeiten und deren Vor- und Nachteile kurz vor.<\/p>\n<p><b>Verkn&uuml;pfte Tabellen und Sichten<\/b><\/p>\n<p>Die Tabellen oder Sichten aus der Datenbank werden im Access-Frontend &uuml;ber ODBC verkn&uuml;pft. Der Zugriff auf die Daten erfolgt &uuml;ber die lokale Frontend-Database-Instanz. Bei Abfragen mit verkn&uuml;pften Tabellen wird die SQL-Anweisung von Jet beziehungsweise ACE (ab Access 2007) entgegengenommen und f&uuml;r die Weitergabe per ODBC an das Datenbanksystem aufbereitet.<\/p>\n<p>Der ODBC-Manager &uuml;bernimmt die aufbereitete SQL-Anweisungen und transferiert sie &uuml;ber den ODBC-Treiber an das DBMS. Das DBMS arbeitet die nun erhaltene SQL-Anweisung ab und gibt das Ergebnis an Jet zur&uuml;ck.<\/p>\n<p>Sobald Jet- beziehungsweise VBA-Funktionen in der Abfrage eingesetzt werden, k&ouml;nnen diese nicht an das DBMS weitergereicht werden und m&uuml;ssen von Jet selbst abgearbeitet werden.<\/p>\n<p>Tipp: Betrachten Sie die vom ODBC-Treiber f&uuml;r den SQL Server aufbereitete SQL-Anweisung und deren Abarbeitung mit dem SQL-Server-Profiler. Der Microsoft SQL Server &uuml;bernimmt auch beim Einsatz von Access-Abfragen mit verkn&uuml;pften Tabellen einen Gro&szlig;teil der Datenaufbereitung und nicht &#8211; wie oftmals behauptet wird &#8211; nur Access und Jet. <\/p>\n<p><b>Zugriffsweg<\/b>: Access &iuml;&euro;&#162; Jet\/ACE &iuml;&euro;&#162; ODBC-Manager &iuml;&euro;&#162; ODBC-Treiber &iuml;&euro;&#162; DBMS<\/p>\n<p><b>Vorteil<\/b>: Vorgehensweise wie bei Access\/Jet-Tabellen und somit wenig Umstellungsaufwand beim Wechsel von einer Jet-Datenbank zu einer Datenbank in einem aktiven DBMS.<\/p>\n<p><b>Nachteil<\/b>: Bei komplexeren Access-Abfragen auf verkn&uuml;pfte Tabellen kann es zu Geschwindigkeitseinbu&szlig;en kommen. Au&szlig;erdem k&ouml;nnen die F&auml;higkeiten des DBMS nicht vollst&auml;ndig eingesetzt werden (etwa Einsatz von gespeicherten Prozeduren).<\/p>\n<p><b>Pass-Through-Abfragen<\/b><\/p>\n<p>Pass-Through-Abfragen erhalten &uuml;ber einen ODBC-Connectionstring eine Verbindung zum DBMS. Bei Pass-Through-Abfragen entf&auml;llt die Auswertung der SQL-Anweisung durch Jet. Daher muss die in einer Pass-Through-Abfrage enthaltene SQL-Anweisung im SQL-Dialekt des DBMS vorliegen.<\/p>\n<p><b>Zugriffsweg<\/b>: Access &iuml;&euro;&#162; ODBC-Manager &iuml;&euro;&#162; ODBC-Treiber &iuml;&euro;&#162; DBMS<\/p>\n<p><b>Vorteil<\/b>: Die SQL-Anweisung wird direkt ohne Umweg &uuml;ber Jet im DBMS ausgef&uuml;hrt. Dadurch k&ouml;nnen die F&auml;higkeiten des DBMS besser genutzt werden.<\/p>\n<p><b>Nachteil<\/b>: Die &uuml;ber eine Pass-Through-Abfrage erhaltenen Datens&auml;tze k&ouml;nnen nicht bearbeitet werden (bei einer verkn&uuml;pften Sicht sind die Datens&auml;tze bearbeitbar, wenn im Access-Frontend ein Prim&auml;rschl&uuml;ssel eingestellt wurde).<\/p>\n<p><b>ADO-Verbindung zur Datenbank<\/b><\/p>\n<p>Der Zugriff erfolgt &uuml;ber einen OLEDB-Provider auf das DBMS. Beachten Sie, dass eine dezidierte Verbindung zum DBMS aufgebaut werden muss und nicht die ADODB-Connection des Frontends &uuml;ber <b>CurrentProject.Connection <\/b>und die verkn&uuml;pften Tabellen genutzt wird. Denn sonst w&uuml;rde der Zugriff abermals &uuml;ber die ODBC-Verbindung laufen.<\/p>\n<p>Damit die Verbindung direkt zum DBMS aufgebaut werden kann, m&uuml;ssen Sie eine ADODB-Connection mit dem OLEDB-Provider des DBMS &ouml;ffnen. F&uuml;r den Zugriff auf einen MSSQL-Server k&ouml;nnen beispielsweise die OLEDB-Provider &#8222;SQLOLEDB&#8220; oder &#8222;SQLNCLI&#8220; verwendet werden. Sollte f&uuml;r ein DBMS, wie bei MySQL, kein spezieller OLEDB-Provider vorhanden sein, k&ouml;nnen Sie als Br&uuml;cke zwischen OLEDB und ODBC den Microsoft OLEDB-Provider f&uuml;r ODBC verwenden und f&uuml;r den Verbindungsaufbau den ODBC-Treiber des DBMS einsetzen. In diesem Fall wird zwar intern wieder &uuml;ber ODBC auf das DBMS zugegriffen, trotzdem k&ouml;nnen Sie die meisten F&auml;higkeiten der ADO-Bibliothek nutzen. Die in ADODB-Methoden eingesetzten SQL-Anweisungen werden &uuml;ber ADO an den OLEDB-Provider &uuml;bergeben und von dort an das DBMS weitergereicht &#8211; &auml;hnlich, wie bei den Pass-Through-Abfragen. Die SQL-Anweisungen m&uuml;ssen daher im jeweiligen SQL-Dialekt des DBMS verfasst werden.<\/p>\n<p><b>Zugriffsweg<\/b>: Access &iuml;&euro;&#162; ADO &iuml;&euro;&#162; OLEDB-Provider &iuml;&euro;&#162; DBMS<\/p>\n<p><b>Vorteil<\/b>: F&uuml;r die meisten aktiven DBMS ist die ADO-Variante die schnellste Zugriffsmethode. Das ADODB-Objektmodell bietet au&szlig;erdem umfangreichere Methoden f&uuml;r den Datenzugriff als das DAO-Objektmodell (zum Beispiel Ausf&uuml;hrung von SQL-Anweisung &uuml;ber <b>ADODB.Command<\/b>).<\/p>\n<p><b>Nachteil<\/b>: Der Programmieraufwand der Standard-ADODB-Methoden ist h&ouml;her als beim DAO-Zugriff. Datenverarbeitung &uuml;ber ADODB kann nur mit VBA oder Formulare genutzt werden. Der Einsatz f&uuml;r Access-Berichte ist in einer <b>.mdb <\/b>beziehungsweise <b>.accdb <\/b>nicht m&ouml;glich (nur beim Einsatz eines ADP-Frontends erfolgt der Zugriff &uuml;ber ADODB\/OLEDB).<\/p>\n<p><b>ODBCDirect<\/b><\/p>\n<p>Mit einem ODBC-Connectionstring wird ein DAO-Arbeitsbereich (<b>DAO.Workspace<\/b>) erstellt. Diese Zugriffsvariante stellt im Prinzip ein DAO-Gegenst&uuml;ck zur ADODB-Verbindung dar. Die SQL-Anweisungen erfolgen im SQL-Dialekt des DBMS.<\/p>\n<p><b>Zugriffsweg<\/b>: Access &iuml;&euro;&#162; ODBCDirect &iuml;&euro;&#162; ODBC-Manager &iuml;&euro;&#162; ODBC-Treiber &iuml;&euro;&#162; DBMS<\/p>\n<p>Da diese Variante ab Access 2007 nicht mehr zur Verf&uuml;gung steht, wird sie im folgenden Text nicht weiter ber&uuml;cksichtigt.<\/p>\n<p><b>DAO-Database-Instanz mit ODBC-Connectionstring <\/b><\/p>\n<p>Mithilfe eines ODBC-Connectionstrings wird eine DAO-Database-Instanz ge&ouml;ffnet. Die SQL-Anweisungen erfolgen im Access\/Jet-SQL-Dialekt. Sie k&ouml;nnen diese Variante mit dem Vorgehen bei einem Jet-Backend vergleichen, bei dem nicht &uuml;ber verkn&uuml;pfte Tabellen auf die Tabellen im Backend zugegriffen wird, sondern auf die Backend-Datenbank &uuml;ber eine eigene Database-Instanz.<\/p>\n<p><b>Zugriffsweg<\/b>: Access &iuml;&euro;&#162; Jet\/ACE &iuml;&euro;&#162; ODBC-Manager &iuml;&euro;&#162; ODBC-Treiber &iuml;&euro;&#162; DBMS<\/p>\n<p><b>Vorteil<\/b>: Tabellen beziehungsweise Sichten m&uuml;ssen nicht verkn&uuml;pft werden. Die Datens&auml;tze im ge&ouml;ffneten Recordset sind bearbeitbar, wenn die verwendete SQL-Anweisung eine Bearbeitung erlaubt.<\/p>\n<p><b>Nachteil<\/b>: Es k&ouml;nnen keine gespeicherten Prozeduren ausgef&uuml;hrt werden.<\/p>\n<p><b>Zusammenfassung<\/b><\/p>\n<p>Jede Verbindungstechnik hat in einem bestimmten Bereich Vorteile. Aus diesem Grund ist der Einsatz einer Kombination ausgew&auml;hlter Techniken im Access-Frontend sinnvoll. F&uuml;r MSSQL oder MySQL k&ouml;nnte etwa folgende Kombination eingesetzt werden:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Verkn&uuml;pfte Tabellen\/Sichten zur Datenbearbeitung in Formularen und als Datenbasis f&uuml;r Berichte (Sortierung und Filterung erfolgt &uuml;ber Access\/Jet-SQL und wird per ODBC an das DBMS weitergereicht)<\/li>\n<li class=\"aufz-hlung\">Pass-Through-Abfragen zur Datenanzeige in Formularen und als Datenbasis f&uuml;r Berichte (SQL-Anweisung kann per VBA angepasst werden)<\/li>\n<li class=\"aufz-hlung\">ADO-Methoden f&uuml;r VBA-Zugriffe und ADO-Recordset als Datenbasis f&uuml;r Formulare und Steuerelemente. (Kombinations- und Listenfelder k&ouml;nnen in einer <b>.mdb<\/b>-Datei erst ab Access 2002 ein ADODB-Recordset als Datenbasis verwenden)<\/li>\n<\/ul>\n<p>Vorteil: Die jeweils passende Technik erm&ouml;glicht effizienten Datenzugriff und Nutzung der F&auml;higkeiten des DBMS.<\/p>\n<p>Nachteil: DAO- und ADO-Methoden m&uuml;ssen unterschiedlich programmiert werden. Das erschwert einen Wechsel der Zugriffstechnik.<\/p>\n<p><b>Beispiel: Recordset &ouml;ffnen<\/b><\/p>\n<p>Das &Ouml;ffnen eines DAO-Recordsets geschieht durch folgende Anweisungen:<\/p>\n<pre>Dim rst As DAO.Recordset\r\nSet rst = CurrentDb.OpenRecordset(\"SELECT *\r\nFROM Tabelle&euro;, dbOpenDynaset, dbSeeChanges)<\/pre>\n<p>Die entsprechende Vorgehensweise f&uuml;r ein ADODB-Recordset ben&ouml;tigt diese Zeilen:<\/p>\n<pre>Dim rst As ADODB.Recordset\r\nSet rst = New ADODB.Recordset\r\nrst.Open \"SELECT * FROM Tabelle&euro;,\r\nCurrentConnection, adOpenDynamic<\/pre>\n<p><b>Ziel dieses Beitrags<\/b><\/p>\n<p>Der Zugriff auf ein DBMS soll standardisiert und DAO- und ADODB-Methoden sollen &uuml;ber eine &auml;hnliche Schnittstelle aufrufbar werden.<\/p>\n<p><b>Ausgangssituation und Konzept<\/b><\/p>\n<p>Ein Access-Frontend wird f&uuml;r den Zugriff auf eine Datenbank in einem aktiven DBMS eingesetzt. Komplexere SQL-Anweisungen werden im DBMS in Form von Sichten und gespeicherten Prozeduren zur Verf&uuml;gung gestellt. Aus diesem Grund ist der Einsatz von ADODB-Methoden beziehungsweise Pass-Through-Abfragen sinnvoll.<\/p>\n<p>Anforderungen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Unabh&auml;ngig vom eingesetzten DBMS<\/li>\n<li class=\"aufz-hlung\">Modularer Aufbau f&uuml;r flexiblen Einbau in Access-Anwendungen<\/li>\n<li class=\"aufz-hlung\">DAO- und ADO-Methoden werden &auml;hnlich aufgerufen.<\/li>\n<\/ul>\n<p>L&ouml;sungsansatz:<\/p>\n<ul>\n<li class=\"aufz-hlung\">DBMS-Verbindung wird &uuml;ber eine Schnittstelle zur <b>DbConnectionInfo<\/b>-Klasse aus dem Beitrag <b>Anmeldung an SQL Server und Co.<\/b> in Heft 3\/2009 (s. Shortlink 668) eingestellt. Die &Uuml;bergabe der Verbindungsparameter wird jedoch so gestaltet, dass die Zugriffsklassenstruktur auch ohne <b>DbConnectionInfo<\/b>-Klasse verwendbar ist.<\/li>\n<li class=\"aufz-hlung\">Klassenmodule f&uuml;r ADODB (OLEDB), DAO (Jet) und DAO (ODBC) dienen zur Kapselung des Datenzugriffs.<\/li>\n<li class=\"aufz-hlung\">Eine zus&auml;tzliche Klasse f&uuml;r die Ansteuerung der Zugriffstechniken erleichtert den Methodenaufruf.<\/li>\n<\/ul>\n<p>Funktionsweise:<\/p>\n<p>&Uuml;ber das Startformular <b>frmAppWatcher<\/b> wird die Startprozedur <b>StartApplication <\/b>aufgerufen. Diese Prozedur startet den Verbindungsaufbau und die Instanzierung der Klasse f&uuml;r die Zugriffssteuerung. Die Verbindungsparameter werden &uuml;ber die <b>DbConnectionInfo<\/b>-Instanz ausgelesen und der Zugriffssteuerung bei Bedarf bereitgestellt. &Uuml;ber die Klasse <b>DbConnectionHandler <\/b>steht ein Objektmodell zur Verf&uuml;gung, dessen Elemente Sie bequem &uuml;ber die Punkt-Syntax ansprechen k&ouml;nnen &#8211; zum Beispiel <b>CurrentDBConnection.ODBC.OpenRecordset(&#8230;)<\/b>.<\/p>\n<p>Das Objektmodell stellt drei verschiedene Zugriffsvarianten zur Verf&uuml;gung:<\/p>\n<ul>\n<li class=\"aufz-hlung\">ADODB (Klasse AdodbHandler)<\/li>\n<li class=\"aufz-hlung\">DAO (Klasse DaoHandler) <\/li>\n<li class=\"aufz-hlung\">ODBC (Klasse OdbcHandler) <\/li>\n<\/ul>\n<p><b>Zugriffsvariante ADODB<\/b><\/p>\n<p>Diese Variante eignet sich f&uuml;r den direkten Zugriff auf die Datenbanken im DBMS. Sie bietet folgende Eigenschaften:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ConnectionString<\/b>: OLEDB-Connectionstring f&uuml;r DBMS-Verbindung<\/li>\n<li class=\"aufz-hlung\"><b>CurrentConnection<\/b>: ADODB-Connection zum DBMS<\/li>\n<\/ul>\n<p>Au&szlig;erdem k&ouml;nnen Sie folgende Methoden f&uuml;r die Ausf&uuml;hrung von SQL-Anweisungen verwenden:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Execute<\/b>: <b>Execute<\/b>-Methode zum Ausf&uuml;hren von SQL-Anweisungen. Syntax: <b>Execute(CommandText, [RecordsAffected], [Options]) As ADODB.Recordset<\/b><\/li>\n<li class=\"aufz-hlung\"><b>InsertIdentityReturn<\/b>: Methode zum Ausf&uuml;hren einer Insert-SQL-Anweisung auf eine Tabelle mit R&uuml;ckgabe des Identity\/Autowerts (<b>IdentityTable <\/b>kann f&uuml;r MSSQL verwendet werden). Syntax: <b>InsertIdentityReturn(InsertSQL, [IdentityTable]) As Variant<\/b><\/li>\n<\/ul>\n<p><!--30percent--><\/p>\n<p>Methoden zum &Ouml;ffnen von Recordsets:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>OpenRecordset<\/b>: Funktioniert wie die herk&ouml;mmliche <b>OpenRecordset<\/b>-Anweisung. Syntax: <b>OpenRecordset(Source, [CursorType], [LockType], [CursorLocation]) As ADODB.Recordset<\/b><\/li>\n<li class=\"aufz-hlung\"><b>OpenRecordsetCommandParam<\/b>: &Ouml;ffnet ein ADODB-Recordset mittels ADODB-Command. Syntax: <b>OpenRecordsetCommandParam(CmdText, CmdType, [commandParamDefs]) As ADODB.Recordset<\/b><\/li>\n<\/ul>\n<p>Recordset-Ersatzfunktionen f&uuml;r Dom&auml;nenfunktionen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>DLookup<\/b>: Funktioniert wie die herk&ouml;mmliche <b>DLookup<\/b>-Funktion. Syntax: <b>DLookup(Expr As String, Domain, [Criteria]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DLookupSQL<\/b>: &auml;hnlich <b>DLookup <\/b>&#8211; nur f&uuml;r direkte &Uuml;bergabe einer SQL-Anweisung. Damit wird etwa unter ADODB der Einsatz einer gespeicherten Prozedur oder Funktion m&ouml;glich. Syntax: <b>DLookupSQL(sSQL, [index]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DSum(Expr, Domain, [Criteria]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DCount(Expr, Domain, [Criteria]) As Long <\/b><\/li>\n<li class=\"aufz-hlung\"><b>DMax (Expr, Domain, [Criteria]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DMin (Expr, Domain, [Criteria]) As Variant<\/b><\/li>\n<\/ul>\n<p><b>Zugriffsvariante DAO<\/b><\/p>\n<p>Diese Variante erm&ouml;glicht den Zugriff &uuml;ber verkn&uuml;pfte Tabellen beziehungsweise den Einsatz von <b>CurrentDb <\/b>des Frontends. Die Klasse bietet nur eine Eigenschaft:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>CurrentDb<\/b>: Liefert eine <b>DAO.Database<\/b>-Instanz des Frontends.<\/li>\n<\/ul>\n<p>Die Methoden f&uuml;r die Ausf&uuml;hrung von SQL-Anweisungen sehen so aus:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Execute<\/b>: F&uuml;hrt eine DAO-Aktionsabfrage aus. Achtung: Die <b>Execute<\/b>-Parameter weichen von der DAO-Execute-Methode ab, da <b>RecordsAffected <\/b>erg&auml;nzt wurde. Syntax: <b>Execute(CommandText, [RecordsAffected], [Options]) As DAO.Recordset<\/b><\/li>\n<li class=\"aufz-hlung\"><b>InsertIdentityReturn<\/b>: Liefert den Autowert des zuletzt hinzugef&uuml;gten Datensatzes. Die Methode funktioniert nicht mit MySQL. F&uuml;r MySQL ist die ADODB-Variante zu verwenden. Syntax: <b>InsertIdentityReturn(InsertSQL) As Variant<\/b><\/li>\n<\/ul>\n<p>Methoden zum &Ouml;ffnen von Recordsets:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>OpenRecordset(Source, [RecordsetType], [RecordsetOptions], [LockEdit]) As DAO.Recordset<\/b><\/li>\n<\/ul>\n<p>Recordset-Ersatzfunktionen f&uuml;r Dom&auml;nenfunktionen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>DLookup: DLookup(Expr As String, Domain, [Criteria]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\">Weitere Funktionen wie unter DAO.<\/li>\n<\/ul>\n<p><b>Zugriffsvariante ODBC <\/b><\/p>\n<p>Diese Klasse dient dem Zugriff &uuml;ber ODBC (dynamische PT-Abfrage beziehungsweise DAO-Database-Instanz mit ODBC-Connectionstring). Sie offeriert folgende Eigenschaften:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ConnectionString<\/b>: ODBC-Connectionstring f&uuml;r DBMS-Verbindung<\/li>\n<li class=\"aufz-hlung\"><b>CurrentDb<\/b>: <b>DAO.Database<\/b>-Instanz des Frontends beziehungsweise der Jet-DB, in der die Pass-Through-Abfragen erstellt werden sollen.<\/li>\n<li class=\"aufz-hlung\"><b>CurrentDbBE<\/b>: <b>DAO.Database<\/b>-Instanz zum Backend (wird mit ODBC-Connectionstring erzeugt)<\/li>\n<\/ul>\n<p>Methoden f&uuml;r die Ausf&uuml;hrung von SQL-Anweisungen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>Execute<\/b>: F&uuml;hrt eine SQL-Anweisung &uuml;ber <b>CurrentDbBE.Execute <\/b>aus. Syntax: <b>Execute(CommandText, [RecordsAffected], [Options])<\/b><\/li>\n<li class=\"aufz-hlung\"><b>ExecutePT<\/b>: F&uuml;hrt die SQL-Anweisung &uuml;ber eine dynamisch erstellte Pass-Through-Anweisung aus. Syntax: <b>ExecutePT(CommandText, [RecordsAffected], [Options])<\/b> <\/li>\n<li class=\"aufz-hlung\"><b>InsertIdentiyReturn<\/b>: Liefert den Autowert des zuletzt hinzugef&uuml;gten Datensatzes. Achtung: Diese Methode funktioniert mit MySQL nicht. F&uuml;r MySQL ist die ADODB-Variante zu verwenden. Syntax: <b>InsertIdentityReturn(InsertSQL) As Variant<\/b><\/li>\n<\/ul>\n<p>Methoden zum &Ouml;ffnen von Recordsets:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>OpenRecordset<\/b>: &Ouml;ffnet ein Recordset &uuml;ber CurrentDbBE. Syntax: <b>OpenRecordset(Source, [RecordsetType], [RecordsetOptions], [LockEdit]) As DAO.Recordset<\/b><\/li>\n<li class=\"aufz-hlung\"><b>OpenRecordsetPT<\/b>: &Ouml;ffnet ein Recordset &uuml;ber eine Pass-Through-Abfrage. Syntax: <b>OpenRecordsetPT(Source, [RecordsetType], [RecordsetOptions], [LockEdit]) As DAO.Recordset<\/b><\/li>\n<\/ul>\n<p>Recordset-Ersatzfunktionen f&uuml;r Dom&auml;nenfunktionen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>DLookup(Expr As String, Domain, [Criteria]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DLookupSQL<\/b>: Greift &uuml;ber <b>CurrentDbBE <\/b>auf die Daten zu, erfordert Jet-SQL-Dialekt. Syntax: <b>DLookupSQL(sSQL, [index]) As Variant<\/b><\/li>\n<li class=\"aufz-hlung\"><b>DLookupSQLPT<\/b>: Zugriff &uuml;ber Pass-Through-Abfrage. Erfordert den SQL-Dialekt des DBMS. Syntax: <b>DLookupSQLPT(sSQL, [index]) As Variant<\/b><\/li>\n<\/ul>\n<p>Die &uuml;brigen Dom&auml;nenfunktionen sind wie unter DAO aufgebaut. Hilfsmethoden:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>LinkTable<\/b>: Verkn&uuml;pft eine Tabelle mit dem Frontend. Syntax: <b>LinkTable(SourceTableName, [LinkedTableName], [bSavePWD], [bRemoveSchemaName])<\/b><\/li>\n<li class=\"aufz-hlung\"><b>RelinkTable<\/b>: Verkn&uuml;pft eine bereits verkn&uuml;pfte Tabelle neu. Syntax: <b>RelinkTable(LinkedTableName, [bSavePWD])<\/b><\/li>\n<li class=\"aufz-hlung\"><b>RelinkTablesAndQueries<\/b>: Erneuert alle bestehenden Verkn&uuml;pfungen. Syntax: <b>RelinkTablesAndQueries([bSavePWD],[lEventCounter]) As Boolean<\/b><\/li>\n<\/ul>\n<p><b>Die Klasse DbConnection<\/b><\/p>\n<p>Eine weitere Klasse namens <b>DbConnection<\/b> liefert weitere hilfreiche Methoden &#8211; zum Beispiel den verk&uuml;rzten Methoden-\/Eigenschaftszugriff von Zugriffsklassen:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>CurrentConnection<\/b>: Zugriff auf <b>ADODB. CurrentConnection<\/b><\/li>\n<li class=\"aufz-hlung\"><b>CurrentDb<\/b>: Zugriff auf <b>DAO.CurrentDb<\/b><\/li>\n<li class=\"aufz-hlung\"><b>CurrentDbBE<\/b>: Zugriff auf <b>ODBC. CurrentDbBE<\/b><\/li>\n<li class=\"aufz-hlung\"><b>OdbcConnectionString<\/b>: Zugriff auf <b>ODBC.Connectionstring<\/b>. Diese Eigenschaft kann zum Einstellen des ODBC-Connectionstrings verwendet werden.<\/li>\n<li class=\"aufz-hlung\"><b>OledbConnectionString<\/b>: Zugriff auf <b>ADODB.Connectionstring<\/b>. Diese Eigenschaft kann zum Einstellen des ADODB\/OLEDB-Connectionstrings verwendet werden.<\/li>\n<\/ul>\n<p>Au&szlig;erdem gibt es Ereignisse zur Probleml&ouml;sung (auch f&uuml;r nachtr&auml;gliche Initialisierung verwendbar). Diese Ereignisse k&ouml;nnen Sie beispielsweise verwenden, um zur Laufzeit f&uuml;r einzelne Zugriffe andere Verbindungszeichenfolgen zu verwenden:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>ErrorEmptyOdbcConnectionString<\/b>: ODBC-Connectionstring fehlt<\/li>\n<li class=\"aufz-hlung\"><b>ErrorEmptyOledbConnectionString<\/b>: OLEDB-Connectionstring fehlt<\/li>\n<li class=\"aufz-hlung\"><b>ErrorMissingCurrentConnection<\/b>: ADODB-Connection fehlt<\/li>\n<li class=\"aufz-hlung\"><b>ErrorMissingCurrentDb<\/b>: <b>CurrentDb<\/b>-Referenz fehlt<\/li>\n<\/ul>\n<p>Wie das aussehen kann, zeigt folgendes Beispiel:<\/p>\n<pre>Private Sub m_DbConnection_ErrorMissingCurrentDb\r\n    (ByVal Msg As String, _\r\n    NewCurrentDbRef As DAO.Database)\r\n    Set NewCurrentDbRef = Application.CurrentDb\r\n    End Sub<\/pre>\n<p><b>Umsetzung<\/b><\/p>\n<p>Auf den folgenden Seiten ist eine Umsetzungsvariante f&uuml;r die zuvor getroffenen Anforderungen beschrieben. Aufgrund des umfangreicheren Codes in der Beispielanwendung werden in der folgenden Beschreibung nur Code-Ausz&uuml;ge gezeigt. Wenn Sie mehr Details zu den gezeigten Prozeduren ben&ouml;tigen, &ouml;ffnen Sie bitte den Code in der Beispielanwendung <b>DBMSZugriff.mdb<\/b>.<\/p>\n<p><b>Einstellen der Verbindungsdaten<\/b><\/p>\n<p>Die Verbindungsdaten werden &uuml;ber die Klasse <b>DbConnectionInfo <\/b>bereitgestellt. Als Schnittstelle zwischen <b>DbConnectionInfo <\/b>und der Zugriffsklasse <b>DbConnectionHandler <\/b>dient die Klasse <b>AccUtilInstancer<\/b>. Die &Uuml;bergabe der Verbindungsparameter erfolgt beim ersten Zugriff auf die Instanz von <b>DbConnectionHandler <\/b>&uuml;ber die Eigenschaft <b>DbConnection <\/b>in <b>AccUtilInstancer <\/b>(s. Listing 1). Sollte noch keine Instanz von <b>DbConnectionInfo <\/b>vorhanden sein, wird diese durch die Verwendung von <b>ConnectionInfo <\/b>erzeugt und die Verbindungsparameter werden ermittelt. Falls Sie sich die Frage stellen, warum <b>DbConnectionInfo <\/b>nicht als Element von <b>DbConnectionHandler <\/b>eingesetzt wird, damit das Instanzieren von zwei Klassen &uuml;ber die Hilfsklasse entf&auml;llt: Durch die Verbindung der Instanzen von <b>DbConnectionHandler <\/b>und <b>DbConnectionInfo <\/b>&uuml;ber <b>AccUtilInstancer <\/b>bleiben die Klassen unabh&auml;ngig voneinander und k&ouml;nnen flexibler eingesetzt werden. Wenn eine Anwendung nur f&uuml;r eine einzige Datenbankverbindung genutzt werden soll, ben&ouml;tigen Sie die Klasse <b>DbConnectionInfo <\/b>nicht, da Sie die Verbindungsparameter als Konstante im VBA-Code ablegen k&ouml;nnen. In diesem Fall m&uuml;ssten Sie <b>Me.ConnectionInfo.OdbcConnectionString <\/b>beziehungsweise <b>Me.ConnectionInfo.OledbConnectionString <\/b>in der Prozedur <b>initDbConnection <\/b>durch eine passende String-Konstante ersetzen.<\/p>\n<p>Beim Zugriff &uuml;ber <b>Me.DbConnection.CurrentDb<\/b>, <b>Me.DbConnection.OdbcConnectionString <\/b>und <b>Me.DbConnection.OledbConnectionString <\/b>wird bereits der erste verk&uuml;rzte Aufruf zu den Zugriffsvarianten aus der <b>DbConnectionHandler<\/b>-Klasse genutzt (s. Listing 2).<\/p>\n<p class=\"kastentabelleheader\">Listing 3: CurrentDbC-Variante in DaoHandler-Klasse<\/p>\n<pre>Private m_DaoDb As DAO.Database\r\nPublic Property Get CurrentDb() As DAO.Database\r\nIf (m_DaoDb Is Nothing) Then\r\n RaiseEvent ErrorMissingCurrentDb( _\r\n    \"DaoHandler.CurrentDb: unavailable CurrentDb-Database&euro;, m_DaoDb)\r\nEnd If\r\nSet CurrentDb = m_DaoDb\r\nEnd Property<\/pre>\n<p>Das Speichern der lokalen DAO-Database-Instanz in der Klasse <b>DaoHandler <\/b>hat den Vorteil, dass bei Bedarf auch eine externe <b>Database<\/b>-Instanz &uuml;bergeben werden k&ouml;nnte. Das ist notwendig, falls Sie die Zugriffsklassen in eine COM-Bibliothek oder &auml;hnliches verschieben wollen. Au&szlig;erdem entsteht dadurch der Effekt, den man &uuml;ber die oft empfohlene <b>CurrentDbC<\/b>-Eigenschaft von Michael Kaplan erreicht (s. Listing 3). Der Unterschied zur &uuml;blichen <b>CurrentDbC<\/b>-Variante ist das Beschaffen einer <b>Database<\/b>-Instanz, falls die Membervariable <b>m_DaoDb <\/b>auf Nothing verweist. In der <b>CurrentDbC<\/b>-Variante von Michael Kaplan w&uuml;rde die Referenz direkt in der <b>Property<\/b>-Prozedur durch <b>Application.CurrentDb <\/b>gesetzt werden. In der <b>CurrentDb<\/b>-Methode der Klasse <b>DaoHandler <\/b>wird ein Ereignis ausgel&ouml;st, auf welches in der Klasse <b>AccUtilInstancer <\/b>reagiert wird (s. Listing 4).<\/p>\n<p class=\"kastentabelleheader\">Listing 5: Einsatz der Klassenstruktur: Test der Recordset-Ersatzfunktionen f&uuml;r DLookup<\/p>\n<pre>Private Sub DLookupTest()\r\n    Dim x As Variant\r\n    x = CurrentDbConnection.ADODB.DLookup(\"FeldA&euro;, \"Tabelle&euro;, \"ID=1&euro;) &euro;ADODB-Variante\r\n    Debug.Print x\r\n    x = CurrentDbConnection.DAO.DLookup(\"FeldA&euro;, \"Tabelle&euro;, \"ID=2&euro;) |DAO-Variante\r\n    Debug.Print x\r\n    x = CurrentDbConnection.ODBC.DLookup(\"FeldA&euro;, \"Tabelle&euro;, \"ID=3&euro;) &euro;ODBC-Variante\r\n    Debug.Print x\r\n    End Sub<\/pre>\n<p class=\"kastentabelleheader\">Listing 7: OpenRecordset-Methode<\/p>\n<pre>&euro;ADODB:\r\nPublic Function OpenRecordset(ByVal Source As String, Optional ByVal CursorType As CursorTypeEnum _\r\n    = adOpenForwardOnly, Optional ByVal LockType AsLockTypeEnum = adLockReadOnly, Optional _\r\n    ByVal CursorLocation As CursorLocationEnum = adUseServer) As ADODB.Recordset\r\n    Dim rst As ADODB.Recordset\r\n    Set rst = New ADODB.Recordset\r\n    With rst\r\n    .CursorLocation = CursorLocation\r\n    .Open Source, Me.CurrentConnection, CursorType, LockType\r\n    End With\r\n    Set OpenRecordset = rst\r\nEnd Function\r\n&euro;DAO:\r\nPublic Function OpenRecordset(ByVal Source As String, Optional ByVal RecordsetType As RecordsetTypeEnum = _\r\n    dbOpenForwardOnly, Optional ByVal RecordsetOptions As RecordsetOptionEnum = dbSeeChanges, Optional ByVal _\r\n    LockEdit As LockTypeEnum = dbOptimistic) As DAO.Recordset\r\n    [...]\r\n    Set OpenRecordset = Me.CurrentDb.OpenRecordset(Source, RecordsetType, RecordsetOptions, LockEdit)\r\nEnd Function\r\n&euro; ODBC:\r\nPublic Function OpenRecordset(ByVal Source As String, Optional ByVal RecordsetType As RecordsetTypeEnum = _\r\n    dbOpenForwardOnly, Optional ByVal RecordsetOptions As RecordsetOptionEnum = dbSeeChanges, Optional _\r\n    ByVal LockEdit As LockTypeEnum = dbOptimistic) As DAO.Recordset\r\n    [...]\r\n    Set OpenRecordset = Me.CurrentDbBE.OpenRecordset(Source, RecordsetType, RecordsetOptions, LockEdit)\r\nEnd Function\r\nPublic Function OpenRecordsetPT(ByVal sSQL As String, Optional ByVal RecordsetType As RecordsetTypeEnum = _\r\n    dbOpenForwardOnly, Optional ByVal RecordsetOptions As RecordsetOptionEnum = dbSeeChanges Or _\r\n    dbSQLPassThrough, Optional ByVal LockEdit As LockTypeEnum = dbOptimistic) As DAO.Recordset\r\n    Dim qdf As DAO.QueryDef\r\n    Dim rst As DAO.Recordset\r\n    [...]\r\n    Set qdf = Me.CurrentDb.CreateQueryDef(\"\")\r\n    With qdf\r\n    .Connect = Me.ConnectionString\r\n    .ODBCTimeout = 0\r\n    .SQL = sSQL\r\n    Set rst = .OpenRecordset(RecordsetType, RecordsetOptions, LockEdit)\r\n    .Close\r\n    End With\r\n    Set OpenRecordsetPT = rst\r\nEnd Function<\/pre>\n<p>Der Vorteil dieser Variante besteht in der Zuweisung der Referenz &uuml;ber das Ereignis. Dadurch ist die Referenz&uuml;bergabe nicht fix in der Klassenstruktur enthalten und kann &uuml;ber die Hauptanwendung gesteuert werden (Anm.: <b>AccUtilInstancer <\/b>ist immer als Teil der Hauptanwendung zu betrachten und wird nie in eine Code-Bibliothek ausgelagert).<\/p>\n<p><b>Einsatz der Zugriffsklassen<\/b><\/p>\n<p>Sobald die Verbindungsparameter &uuml;bergeben wurden, sind die Zugriffsmethoden einsatzbereit (s. Listing 5). Der Zugriff auf die <b>DbConnectionHandler<\/b>-Instanz erfolgt &uuml;ber die <b>Property<\/b>-Prozedur <b>CurrentDbConnection <\/b>im Modul <b>modAccessUtilities<\/b> (s. Listing 6).<\/p>\n<p class=\"kastentabelleheader\">Listing 9: OpenAdoRecordset-Funktion im Modul modADO<\/p>\n<pre>Public Function OpenAdoRecordset(ByVal Source As String, Optional ByVal CursorType As CursorTypeEnum = _\r\n    adOpenForwardOnly, Optional ByVal LockType As LockTypeEnum = adLockReadOnly, _\r\n    Optional ByVal CursorLocation As CursorLocationEnum = adUseServer) As ADODB.Recordset\r\n    Set OpenAdoRecordset = CurrentDbConnection.ADODB.OpenRecordset(Source, CursorType, LockType, CursorLocation)\r\nEnd Function<\/pre>\n<p>Die <b>Property<\/b>-Prozedur <b>CurrentDbConnection <\/b>stellt die anwendungsweite <b>DbConnectionHandler<\/b>-Instanz zur Verf&uuml;gung.<\/p>\n<p>&Uuml;ber die Eigenschaften ADODB, DAO beziehungsweise ODBC k&ouml;nnen Sie die gew&uuml;nschte Zugriffstechnik w&auml;hlen. ADODB greift &uuml;ber die ADODB-Connection auf die Datenbank zu. DAO nutzt die verkn&uuml;pfte Tabelle im Access-Frontend und ODBC setzt eine auf einer ODBC-Verbindung basierende DAO-Database-Instanz ein.<\/p>\n<p>Die nahezu identisch aufgebauten Methoden in den Zugriffsklassen erleichtern die Wahl der Zugriffsmethode, da Sie sich nur noch einen Methodennamen f&uuml;r drei Zugriffsvarianten merken m&uuml;ssen.<\/p>\n<p><b>Code-Ausz&uuml;ge: OpenRecordset<\/b><\/p>\n<p>Die Methode <b>OpenRecordset <\/b>gibt &uuml;ber die <b>AdodbHandler<\/b>-Klasse ein ge&ouml;ffnetes <b>ADODB<\/b>-Recordset zur&uuml;ck. <b>DaoHandler <\/b>und <b>OdbcHandler <\/b>liefern ein DAO-Recordset (s. Listing 7).<\/p>\n<p>In der <b>OpenRecordset<\/b>-Methode der Zugriffsklassen wird der jeweilige Zugriffscode (ADODB oder DAO) gekapselt. Damit m&uuml;ssen Sie sich im restlichen Code nicht mehr um die unterschiedliche Erstellung eines Recordsets je Zugriffsvariante k&uuml;mmern.<\/p>\n<p>Bei der Verwendung dieser Methoden m&uuml;ssen Sie allerdings die passende SQL-Syntax beachten. Vor allem beim <b>Like<\/b>-Ausdruck werden manchmal die unterschiedlichen Platzhalter &uuml;bersehen (DAO: <b>*<\/b>, ADODB und ODBC-Pass-Through: <b>%<\/b>).<\/p>\n<p>Die restlichen Methoden sind &auml;hnlich aufgebaut und beliebig erweiterbar. Es ist hilfreich, wenn Sie die Recordset-Ersatzfunktionen f&uuml;r die Dom&auml;nenfunktionen <b>DLookup<\/b>, <b>DMax <\/b>und so weiter in den Zugriffsklassen kapseln. Beispiele f&uuml;r erweiterte Dom&auml;nenfunktionen werden im Artikel <b>Schnelle Dom&auml;nenfunktionen <\/b>aus Heft 3\/2009 gezeigt (s. Shortlink 644). <\/p>\n<p><b>Tabellen verkn&uuml;pfen<\/b><\/p>\n<p>In der <b>OdbcHandler<\/b>-Klasse sind zus&auml;tzlich einige Hilfsmethoden zum Verkn&uuml;pfen von Tabellen enthalten. Einen m&ouml;glichen Anwendungsfall sehen Sie im Formular <b>frmConfig_LinkTables<\/b>. Dieses Formular erm&ouml;glicht die Wartung der verkn&uuml;pften Tabellen. Zur Visualisierung der durchgef&uuml;hrten Verkn&uuml;pfungsaktualisierung werden Ereignisse aus der Klasse <b>OdbcHandler <\/b>eingesetzt (s. Listing 8).<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Methodenaufruf abk&uuml;rzen<\/p>\n<p>Ist Ihnen das Schreiben von <b>CurrentDbConnection.ADODB.OpenRecordset(&#8230;) <\/b>zu aufwendig Dann verk&uuml;rzen Sie den Aufruf mithilfe einer Funktion in einem allgemeinen Modul (s. Listing 9).<\/p>\n<p><b>Zus&auml;tzliche DBMS-Verbindungen verwenden<\/b><\/p>\n<p>Sollten Sie eine weitere DBMS-Verbindung ben&ouml;tigen, k&ouml;nnen Sie eine neue Instanz von <b>DbConnectionHandler <\/b>erzeugen und die passenden Verbindungsparameter in Form eines ODBC- und\/oder OLEDB-Connectionstrings &uuml;bergeben:<\/p>\n<pre>Dim dbc As DbConnectionHandler\r\nSet dbc = New DbConnectionHandler\r\ndbc.OledbConnectionString = \"Provider=SQLOLEDB;\r\nData Source=...;Initial Catalog=...;\r\nIntegrated Security = SSPI;&euro;\r\nDebug.Print dbc.ADODB.DLookupSQL( _\r\n\"Select Count(*) FROM Tabelle WHERE\r\nFeldA like &euro;abc%&euro;&#153;&euro;)<\/pre>\n<p>Mit diesem Beispiel wird der Vorteil einer Klassenstruktur gut erkennbar. W&uuml;rde der Zugriffscode &uuml;ber eine Funktion in einem allgemeinen Modul ablaufen, m&uuml;ssten zus&auml;tzliche Parameter zur Connectionstring-&Uuml;bergabe vorhanden sein, damit die Funktion f&uuml;r mehrere parallele DBMS-Verbindungen genutzt werden kann.<\/p>\n<p>Das entf&auml;llt beim Einsatz von Klassen, da jede erzeugte Instanz unterschiedlich einstellbar ist.<\/p>\n<p><b>Einsatz in Formularen<\/b><\/p>\n<p>Wenn Sie in einem Formular die Daten aus einem ADODB-Recordset anzeigen wollen, k&ouml;nnen Sie die ADODB-Recordset-Referenz dem Formular-Recordset &uuml;bergeben:<\/p>\n<pre>Set Me.Recordset = CurrentDbConnection. _\r\nADODB.OpenRecordset(strSQL, adOpenDynamic, _\r\nadLockOptimistic, adUseClient)<\/pre>\n<p>Bei diesem Code m&uuml;ssen Sie beachten, dass Sie die <b>CursorLocation <\/b>auf <b>adUseClient <\/b>setzen. Das Formular <b>frmTest_Zugriffsvarianten <\/b>zeigt ein ausf&uuml;hrlicheres Beispiel, wie Sie die unterschiedlichen Zugriffstechniken als Datenquelle f&uuml;r ein Formular einsetzen k&ouml;nnen (siehe Bild 1).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_04\/DBMS-web-images\/frmTest_Zugriffsvarian_opt.jpeg\" alt=\"frmTest_Zugriffsvarianten.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Formular zum Testen unterschiedlicher Zugriffstechniken<\/span><\/b><\/p>\n<p>&Uuml;ber die Auswahl der Datenbasis im linken unteren Listenfeld wird die jeweilige Zugriffstechnik zur Datenanzeige im Unterformular verwendet (s. Listing 12).<\/p>\n<p>Mit diesem Formular k&ouml;nnen Sie testen, wie sich die unterschiedlichen Zugriffstechniken auf die Bearbeitbarkeit der Datens&auml;tze auswirken.<\/p>\n<p><b>Zusammenfassung und Ausblick<\/b><\/p>\n<p>Die hier vorgestellten Methoden zum Zugriff auf ein aktives DBMS &uuml;ber ADO\/OLEDB oder DAO\/ODBC sind als Basis f&uuml;r eine umfangreiche Methodensammlung zu betrachten. <\/p>\n<p>F&uuml;r den Ausbau Ihrer Klassenstruktur haben wir noch einige Anregungen:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Erg&auml;nzen Sie die Klassenstruktur um weitere Klassen zur Steuerung von Formularen und Steuerelementen.<\/li>\n<li class=\"aufz-hlung\">Sichern Sie die DBMS-Zugriffe &uuml;ber zusammengesetzte SQL-Anweisungen gegen SQL-Injection ab (m&ouml;glicher Angriff auf das DBMS!), falls Teile des SQL-Strings vom Benutzer eingeben werden k&ouml;nnen. <\/li>\n<li class=\"aufz-hlung\">Erstellen Sie Methoden zum dynamischen Erzeugen von Filterausdr&uuml;cken f&uuml;r SQL-Anweisungen.<\/li>\n<li class=\"aufz-hlung\">Lagern Sie die Klassenstruktur in eine COM-Bibliothek (DLL) beziehungsweise mde-Bibliothek aus.<\/li>\n<\/ul>\n<p class=\"kastentabelleheader\">Listing 2: Verbindung in der Zugriffsklasse DbConnectionHandler einstellen<\/p>\n<pre>&euro;Zugriff auf die Database-Instanz des Frontend\r\nPublic Property Set CurrentDb(ByRef NewCurrentDb As DAO.Database)\r\nSet Me.DAO.CurrentDb = NewCurrentDb\r\nEnd Property\r\nPublic Property Get DAO() As DaoHandler\r\nIf m_DaoHandler Is Nothing Then\r\n Set m_DaoHandler = New DaoHandler\r\nEnd If\r\nSet DAO = m_DaoHandler\r\nEnd Property\r\n&euro;ODBC-Verbindung\r\nPublic Property Let OdbcConnectionString(ByVal sConnectionString As String)\r\nMe.ODBC.ConnectionString = sConnectionString\r\nEnd Property\r\nPublic Property Get ODBC() As OdbcHandler\r\nIf m_OdbcHandler Is Nothing Then\r\n Set m_OdbcHandler = New OdbcHandler\r\nEnd If\r\nSet ODBC = m_OdbcHandler\r\nEnd Property\r\n&euro;ADOB-Verbindung\r\nPublic Property Let OledbConnectionString(ByVal sConnectionString As String)\r\nMe.ADODB.ConnectionString = sConnectionString\r\nEnd Property\r\nPublic Property Get ADODB() As AdodbHandler\r\nIf m_AdodbHandler Is Nothing Then\r\n Set m_AdodbHandler = New AdodbHandler\r\nEnd If\r\nSet ADODB = m_AdodbHandler\r\nEnd Property<\/pre>\n<p class=\"kastentabelleheader\">Listing 4: Reaktion auf ErrorMissingCurrentDb in AccUtilInstancer mit &Uuml;bergabe der Database-Referenz<\/p>\n<pre>Private Sub m_DbConnection_ErrorMissingCurrentDb(ByVal Msg As String, _\r\n    NewCurrentDbRef As DAO.Database)\r\n    Set NewCurrentDbRef = Application.CurrentDb\r\n    End Sub<\/pre>\n<p class=\"kastentabelleheader\">Listing 6: Zugriff auf DbConnectionHandler-Instanz<\/p>\n<p class=\"kastentabelleheader\">Listing 12: Unterschiedliche Zugriffstechniken testen<\/p>\n<p class=\"kastentabelleheader\">Listing 1: Verbindungsinitialisierung in der Klasse AccUtilInstancer<\/p>\n<pre>Public Property Get DbConnection() As DbConnectionHandler\r\nIf m_DbConnection Is Nothing Then\r\n Set m_DbConnection = New DbConnectionHandler\r\n    initDbConnection\r\nEnd If\r\nSet DbConnection = m_DbConnection\r\nEnd Property\r\nPrivate Sub initDbConnection()\r\n    Set Me.DbConnection.CurrentDb = Application.CurrentDb\r\n    &euro; ... CurrentDb-&Uuml;bergabe ist nicht unbedingt erforderlich,\r\n    &euro; wird bei Bedarf &uuml;ber Event angefordert\r\n    Me.DbConnection.OdbcConnectionString = Me.ConnectionInfo.OdbcConnectionString\r\n    Me.DbConnection.OledbConnectionString = Me.ConnectionInfo.OledbConnectionString\r\n    End Sub\r\n&euro;Code in frmTest_Zugriffsvarianten:\r\nPrivate Sub setSfrDataMode()\r\n    Dim strTabName As String\r\n    strTabName = Nz(Me!lstTab, vbNullString)\r\n    Me.sfrConnTest.Form.SetDataMode Nz(Me!lstDataMode, 0), strTabName\r\n    End Sub\r\n&euro;Code in frmTest_Zugriffsvarianten_SF_Daten\r\n&euro;(UF von frmTest_Zugriffsvarianten):\r\nPublic Sub SetDataMode(ByVal lDataMode As Long, ByVal sTabName As String)\r\n&euro;lDataMode:\r\n&euro; 1 .. verkn&uuml;pfte Tabelle\r\n&euro; 2 .. DAO-Recordset auf BE\r\n&euro; 3 .. DAO-Recordset von PT-Abfrage\r\n&euro; 4 .. ADO-Recordset auf BE\r\n[...]\r\nSelect Case lDataMode\r\nCase 1 &euro;verkn&uuml;pfte Tabelle\r\n&euro;Recordset wieder auf DAO-Recordset setzen\r\n&euro;.. ist erforderlich, falls zuvor ADODB-Recordset verwendet wurde\r\nIf Not Me.Recordset Is Nothing Then\r\n If TypeOf Me.Recordset Is ADODB.Recordset Then\r\n    Set Me.Recordset = CurrentDbConnection.DAO.OpenRecordset(\"select * from tab1DS where 1=0&euro;, dbOpenDynaset)\r\n    Me.Recordset.Close\r\n    Set Me.Recordset = Nothing\r\nEnd If\r\nEnd If\r\n&euro;Datenbasis einstellen\r\nMe.RecordSource = sTabName\r\nMe.labDataMode.Caption = \"verkn&uuml;pfte Tabelle&euro;\r\nsetControls_DAO\r\nCase 2 &euro;DAO-Recordset auf BE\r\nSet Me.Recordset = CurrentDbConnection.ODBC.OpenRecordset(\"select * from [\" &amp; sTabName &amp; \"]&euro;, _\r\ndbOpenDynaset, dbSeeChanges)\r\nMe.labDataMode.Caption = \"DAO-Recordset auf BE&euro;\r\nsetControls_DAO\r\nCase 3 &euro;DAO-Recordset &uuml;ber PT-Abfrage\r\nSet Me.Recordset = CurrentDbConnection.ODBC.OpenRecordsetPT(\"select * from \" &amp; sTabName, dbOpenDynaset)\r\nMe.labDataMode.Caption = \"DAO-Recordset &uuml;ber PT&euro;\r\nCase 4 &euro;ADO-Recordset auf BE\r\nstrSQL = \"select * from \" &amp; sTabName\r\nSet Me.Recordset = CurrentDbConnection.ADODB.OpenRecordset(strSQL, adOpenKeyset, adLockOptimistic, adUseClient)\r\nMe.labDataMode.Caption = \"ADO-Recordset auf BE&euro;\r\nsetControls_ADO\r\nCase Else\r\nMe.RecordSource = vbNullString\r\nMe.labDataMode.Caption = vbNullString\r\nEnd Select\r\nEnd Sub\r\nPublic Property Get CurrentDbConnection() As DbConnectionHandler\r\nIf m_AccessUtilsApplicationInstancer Is Nothing Then\r\n Set m_AccessUtilsApplicationInstancer = New AccUtilInstancer\r\nEnd If\r\nSet CurrentDbConnection = m_AccessUtilsApplicationInstancer.DbConnection\r\nEnd Property<\/pre>\n<p class=\"kastentabelleheader\">Listing 8: Tabellen verkn&uuml;pfen<\/p>\n<pre>&euro; Code im Formular frmConfig_LinkTables\r\n&euro; -------------------------------------\r\nPrivate WithEvents m_OdbcHandler As OdbcHandler\r\n&euro; Verkn&uuml;pfung der bereits vorhandenen Tabellen starten:\r\nPrivate Sub startReconnectOdbc()\r\n    Me.labObjectCounter.Caption = \"Tabellen\/Abfragen wurden verkn&uuml;pft&euro;\r\n    Set m_OdbcHandler = CurrentDbConnection.ODBC\r\n    m_OdbcHandler.RelinkTablesAndQueries CurrentConnectionInfo.SavePassword, 1\r\n    End Sub\r\n&euro; Anzeige des Verkn&uuml;pfungsvorgangs\r\nPrivate Sub m_OdbcHandler_DbObjectRelinked(ByVal LastDbObjectName As String, ByVal lCounter As Long)\r\n    Me.txtLastObjectName.Value = LastDbObjectName\r\n    Me.txtObjectCounter.Value = lCounter\r\n    Me.Repaint &euro;erforderlich, damit &auml;nderungen sichtbar werden\r\n    End Sub\r\n&euro; Code im OdbcHandler-Klassenmodul\r\n&euro; --------------------------------\r\nPublic Event DbObjectRelinked(ByVal LastDbObjectName As String, ByVal lCounter As Long)\r\nPublic Function RelinkTablesAndQueries( Optional ByVal bSavePWD As Boolean = False, _\r\n    Optional ByVal lEventCounter As Long = 0) As Boolean\r\n    Dim dbs As DAO.Database\r\n    Dim tdf As DAO.TableDef\r\n    Dim qdf As DAO.QueryDef\r\n    Dim lConnectCounter As Long\r\n    Set dbs = Me.CurrentDb\r\n    &euro; Tabellen\r\n    dbs.TableDefs.Refresh\r\n    For Each tdf In dbs.TableDefs\r\n        With tdf\r\n        If Left$(.Connect, 4) = \"ODBC&euro; Then\r\n            .Connect = Me.ConnectionString\r\n            .RefreshLink\r\n            [...]\r\n            If lEventCounter &gt; 0 Then &euro;0 ... R&uuml;ckgabe ist deaktiviert\r\n            lConnectCounter = lConnectCounter + 1\r\n            If lConnectCounter Mod lEventCounter = 0 Then\r\n                RaiseEvent DbObjectRelinked(.Name, lConnectCounter)\r\n            End If\r\n        End If\r\n    End If\r\n    End With\r\nNext tdf\r\n&euro; Abfragen\r\n[...]\r\nRelinkTablesAndQueries = True\r\nEnd Function<\/pre>\n<p class=\"kastentabelleheader\">Listing 10: Zus&auml;tzliche DbConnectionHandler-Instanz verwenden<\/p>\n<pre>Public Function OpenAdoRecordset(ByVal Source As String, Optional ByVal CursorType As CursorTypeEnum = _\r\nadOpenForwardOnly, Optional ByVal LockType As LockTypeEnum = adLockReadOnly, _\r\nOptional ByVal CursorLocation As CursorLocationEnum = adUseServer) As ADODB.Recordset\r\nSet OpenAdoRecordset = CurrentDbConnection.ADODB.OpenRecordset(Source, CursorType, LockType, CursorLocation)\r\nEnd Function<\/pre>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>DbmsZugriff.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{00310B85-EBD5-4E56-8795-551F0593C788}\/aiu_677.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Haben Sie sich nicht auch schon immer gefragt, welche Zugriffstechnik am besten f&uuml;r den Zugriff auf Tabellen in aktiven Datenbanksystemen geeignet ist Falls Sie dies bereits mit ADODB- und DAO-Methoden getestet haben, wissen Sie vermutlich, dass keine Zugriffsmethode alle W&uuml;nsche eines Access-Programmierers erf&uuml;llt. Es bleibt also nichts anderes &uuml;brig, als die Einschr&auml;nkungen hinzunehmen oder unterschiedliche Methoden parallel einzusetzen.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662009,66042009,44000022],"tags":[],"class_list":["post-55000677","post","type-post","status-publish","format-standard","hentry","category-662009","category-66042009","category-SQL_Server_und_Co"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co. - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co.\" \/>\n<meta property=\"og:description\" content=\"Haben Sie sich nicht auch schon immer gefragt, welche Zugriffstechnik am besten f&uuml;r den Zugriff auf Tabellen in aktiven Datenbanksystemen geeignet ist Falls Sie dies bereits mit ADODB- und DAO-Methoden getestet haben, wissen Sie vermutlich, dass keine Zugriffsmethode alle W&uuml;nsche eines Access-Programmierers erf&uuml;llt. Es bleibt also nichts anderes &uuml;brig, als die Einschr&auml;nkungen hinzunehmen oder unterschiedliche Methoden parallel einzusetzen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:16:52+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"24\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co.\",\"datePublished\":\"2020-05-22T22:16:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/\"},\"wordCount\":3698,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/0e9928b83c004fa9a2e52b7a2bd2c351\",\"articleSection\":[\"2009\",\"4\\\/2009\",\"SQL Server und Co.\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/\",\"name\":\"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co. - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/0e9928b83c004fa9a2e52b7a2bd2c351\",\"datePublished\":\"2020-05-22T22:16:52+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/0e9928b83c004fa9a2e52b7a2bd2c351\",\"contentUrl\":\"http:\\\/\\\/vg05.met.vgwort.de\\\/na\\\/0e9928b83c004fa9a2e52b7a2bd2c351\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co.\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co. - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/","og_locale":"de_DE","og_type":"article","og_title":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co.","og_description":"Haben Sie sich nicht auch schon immer gefragt, welche Zugriffstechnik am besten f&uuml;r den Zugriff auf Tabellen in aktiven Datenbanksystemen geeignet ist Falls Sie dies bereits mit ADODB- und DAO-Methoden getestet haben, wissen Sie vermutlich, dass keine Zugriffsmethode alle W&uuml;nsche eines Access-Programmierers erf&uuml;llt. Es bleibt also nichts anderes &uuml;brig, als die Einschr&auml;nkungen hinzunehmen oder unterschiedliche Methoden parallel einzusetzen.","og_url":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:16:52+00:00","og_image":[{"url":"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"24\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co.","datePublished":"2020-05-22T22:16:52+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/"},"wordCount":3698,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351","articleSection":["2009","4\/2009","SQL Server und Co."],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/","url":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/","name":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co. - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#primaryimage"},"thumbnailUrl":"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351","datePublished":"2020-05-22T22:16:52+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#primaryimage","url":"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351","contentUrl":"http:\/\/vg05.met.vgwort.de\/na\/0e9928b83c004fa9a2e52b7a2bd2c351"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/DBMSunabhaengiger_Zugriff_auf_SQL_Server_und_Co\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"DBMS-unabh&auml;ngiger Zugriff auf SQL Server und Co."}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000677","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000677"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000677\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000677"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000677"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000677"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}