{"id":55000662,"date":"2009-04-01T00:00:00","date_gmt":"2020-05-22T22:22:44","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=662"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Verknuepfte_Datenbanken_updaten","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/","title":{"rendered":"Verkn&uuml;pfte Datenbanken updaten"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Wer Software f&uuml;r einen Kunden entwickelt und nicht st&auml;ndig an der Produktiv-Version arbeitet, steht irgendwann vor der Anforderung, die Produktiv-Version gegen die neue Version auszutauschen. Dieser Beitrag zeigt eine M&ouml;glichkeit, ein solches Update ohne Reibungsverluste durchzuf&uuml;hren.<\/b><\/p>\n<p>Zum Update einer Datenbank k&ouml;nnen mehrere Faktoren geh&ouml;ren. Es kann sein, dass man nur einen kleinen Fehler im Code behoben hat und dem Benutzer die neue Version zukommen lassen m&ouml;chte &#8211; kein Problem, man tauscht einfach das am besten in einer Frontend-Backend-Konfiguration enthaltene Frontend aus und verkn&uuml;pft das neue Frontend mit den Tabellen des alten Backends.<\/p>\n<p>Oder man stellt fest, dass man ein wichtiges Feld im Datenmodell vergessen hat. Das wird schon schwieriger: Das Backend mit dem Datenmodell kann man nicht so schnell austauschen, denn es enth&auml;lt ja die aktuell benutzten Daten. In dem Fall wird man am einfachsten zum Kunden fahren und das Datenmodell vor Ort &auml;ndern oder dies per Fernwartung erledigen. Ist beides nicht m&ouml;glich, leitet man den Kunden durch diesen Vorgang, was erfahrungsgem&auml;&szlig; je nach dessen Fertigkeiten kompliziert werden kann.<\/p>\n<p>Sobald jedoch mehr als ein Kunde mit derselben Datenbank arbeitet oder h&auml;ufige oder viele &auml;nderungen vorgenommen werden sollen, f&auml;llt die oben beschriebene Vorgehensweise flach.<\/p>\n<p>Vielleicht treffen ja auch &auml;nderungen am Frontend und am Backend zusammen, was zumindest dann der Regelfall ist, wenn das Backend betroffen ist &#8211; &auml;nderungen am Frontend sind dann nicht ganz unwahrscheinlich.<\/p>\n<p>Diese Kombination trifft sich gut, denn wenn man dem Kunden ein neues Frontend mit ge&auml;nderter Benutzeroberfl&auml;che oder Anwendungslogik verpasst, kann man &auml;nderungen am Datenmodell gleich durch diese neue Version des Frontends erledigen lassen.<\/p>\n<p>Genau wie einige andere Vorg&auml;nge, die normalerweise beim &Ouml;ffnen der Datenbank ablaufen &#8211; also etwa das Pr&uuml;fen des Backends und der Verkn&uuml;pfungen zu den Tabellen im Backend oder die Konsistenzpr&uuml;fung bestehender Daten -, k&ouml;nnen Sie hier auch &auml;nderungen am Datenmodell des Backends durchf&uuml;hren lassen.<\/p>\n<p><b>Von A nach B<\/b><\/p>\n<p>Wenn Sie eine Datenbankanwendung nur f&uuml;r einen Kunden erstellt haben und weiterentwickeln, liegt eine komfortable Situation vor. Ausgehend davon, dass der Kunde neue Versionen immer direkt einsetzt, brauchen Sie beim Start des neuen Frontends nur ein paar Codezeilen aufzurufen, welche die seit dem letzten Update angefallenen &auml;nderungen am Datenmodell durchf&uuml;hren.<\/p>\n<p>Jedes weitere Update geht dann vom jeweils durch die Vorversion hergestellten Zustand aus und passt das Backend seinerseits an.<\/p>\n<p>Ganz anders sieht es aus, wenn zwei oder mehr Benutzer die Dienste Ihrer Datenbank in Anspruch nehmen, wobei &#8222;mehrere Benutzer&#8220; nicht im Sinne von Mehrbenutzerumgebung, sondern von eigenst&auml;ndigen Anwendern mit eigenem Front- und Backend gemeint ist.<\/p>\n<p>Nehmen wir an, es g&auml;be der Einfachheit halber nur zwei Benutzer, von denen der eine die Anwendung in Version 1.0 betreibt und der andere bereits ein Update auf die Version 1.1 vorgenommen hat &#8211; der erste Benutzer hat dies schlicht ausgelassen.<\/p>\n<p>Wenn Sie nun eine neue Version 1.2 ver&ouml;ffentlichen, k&ouml;nnen Sie nicht mehr einfach nur davon ausgehen, dass diese Version &uuml;berall die gleichen Voraussetzungen antrifft, um die in Version 1.2 enthaltenen &auml;nderungen etwa am Backend durchzuf&uuml;hren.<\/p>\n<p>Eine Tabelle, die in Version 1.1 hinzugef&uuml;gt wurde und in Version 1.2 um ein weiteres Feld erg&auml;nzt werden soll, w&auml;re beim Update von Version 1.0 auf Version 1.2 noch gar nicht vorhanden und w&uuml;rde so zu einem Fehler beim Hinzuf&uuml;gen des Feldes zur nicht vorhandenen Tabelle f&uuml;hren.<\/p>\n<p>Bevor jemand auf die Idee kommt: Es kommt nat&uuml;rlich nicht infrage, dass der Kunde nacheinander alle Zwischenversionen installiert, wenn er den Schritt von Version 1.0 etwa zu Version 1.6 machen m&ouml;chte.<\/p>\n<p>Sie m&uuml;ssen also zumindest eine &Uuml;berpr&uuml;fung einbauen, mit welcher Version die Anwender arbeiten, und selbst daf&uuml;r sorgen, dass die &auml;nderungen der einzelnen Versionen inkrementell durchgef&uuml;hrt werden &#8211; auch wenn der Anwender gleich mehrere Versionen &uuml;berspringt.<\/p>\n<p><b>Verkn&uuml;pft und zugen&auml;ht<\/b><\/p>\n<p>Als kleines Bonbon kommt noch hinzu, dass neu im Backend angelegte Tabellen erst noch verkn&uuml;pft und die Verkn&uuml;pfungen ge&auml;nderter Tabellen aktualisiert werden m&uuml;ssen.<\/p>\n<p>Bevor Sie eine neue Version der Software verteilen, werden Sie vermutlich schon alle notwendigen Verkn&uuml;pfungen angelegt haben, sodass diese beim Update nicht mehr hinzugef&uuml;gt werden m&uuml;ssen (es w&auml;re auch Unsinn, ein Frontend auszutauschen und dieses beim ersten Start nach dem Austausch dazu zu bringen, sich selbst anzupassen, indem es einige Verkn&uuml;pfungen hinzuf&uuml;gt).<\/p>\n<p>Normalerweise sollten Sie aufgeteilten Datenbanken aber ohnehin einen Mechanismus mitgeben, der jeweils beim Anwendungsstart pr&uuml;ft, ob das Backend an Ort und Stelle ist, und die Verkn&uuml;pfungen aktualisiert.<\/p>\n<p>Und da dieser doch recht eng mit dem Anlegen neuer Tabellen beim Update der Anwendung verkn&uuml;pft ist, liefern wir diesen Mechanismus in diesem Beitrag gleich mit.<\/p>\n<p><b>Aufbau<\/b><\/p>\n<p>Die nachfolgend vorgestellten Techniken setzen ein paar Faktoren voraus. Zun&auml;chst einmal besteht das besprochene System wie erw&auml;hnt aus einer Frontend- und einer Backenddatenbank, wobei die Benutzeroberfl&auml;che (also Formulare, Berichte und Men&uuml;leisten), die Anwendungslogik und die Abfragen im Frontend und die durch die Anwendung zu verwaltenden Daten in entsprechenden Tabellen im Backend gespeichert sind.<\/p>\n<p>Damit Sie im Frontend auf die in den Tabellen des Backends enthaltenen Daten genau so zugreifen k&ouml;nnen, als ob diese im Frontend enthalten w&auml;ren, legen Sie im Frontend eine Reihe von Verkn&uuml;pfungen an, die das Datenbankfenster (Access 2003) oder der Navigationsbereich (Access 2007) mit entsprechenden Symbolen ausgestattet im Bereich <b>Tabellen <\/b>auff&uuml;hrt (siehe Bild 1).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/pic001_opt.jpeg\" alt=\"pic001.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 1: Verkn&uuml;pfte Tabellen werden durch besondere Symbole markiert.<\/span><\/b><\/p>\n<p>In dieser Abbildung sehen Sie gleich eine recht wichtige Tabelle, die entscheidend f&uuml;r die hier vorgestellte Technik ist: <b>tbl_VersionBE<\/b>. Diese Tabelle enth&auml;lt nur ein Feld namens <b>Version<\/b>, das die Nummer der aktuellen Version speichert. In Bild 2 ist dies die Nummer <b>0.904<\/b>. Wichtig: Nat&uuml;rlich muss sich diese Tabelle im Backend befinden und ist mit dem Frontend lediglich verkn&uuml;pft! Anderenfalls w&uuml;rde diese ja mit jeder neuen Version des Frontends ausgetauscht.<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/pic002_opt.jpeg\" alt=\"pic002.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 2: Tabelle zum Speichern der Versionsnummer des Backends<\/span><\/b><\/p>\n<p>Dem Frontend k&ouml;nnen Sie eine &auml;hnliche Tabelle beispielsweise mit dem Namen <b>tbl_VersionFE <\/b>hinzuf&uuml;gen. Einen neuen Wert enth&auml;lt die Tabelle mit jeder neuen Version des Frontends.<\/p>\n<p>Es kann sehr n&uuml;tzlich sein, wenn Sie Informationen &uuml;ber die Version von Frontend und Backend an gut sichtbarer Stelle unterbringen, damit der Benutzer Ihnen diese bei Problemen gegebenenfalls leicht mitteilen kann; f&uuml;r die Fehlerbehandlung sind diese Informationen nat&uuml;rlich ebenfalls hochinteressant (vielleicht lassen Sie sich die Fehlermeldungen bei Laufzeitfehlern per E-Mail zusenden, dann sollten Informationen &uuml;ber die Version von Frontend und Backend nicht fehlen &#8211; neben Modul, Prozedurname, Zeile, Fehlernummer et cetera).<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Ablauf<\/p>\n<p>Bevor wir uns den Code ansehen, der f&uuml;r das Verkn&uuml;pfen und Updaten des Backends sorgt (nicht vergessen: das Update des Frontends erfolgt ganz einfach durch seinen Austausch, das neue Frontend f&uuml;hrt dann das Update des Backends aus!), schauen wir uns den Ablauf im &Uuml;berblick an.<\/p>\n<p>Diesen verschafft Abb. 3, die alle Schritte der im Modul <b>mdlGlobal <\/b>befindlichen Funktion <b>StartDB <\/b>der Beispieldatenbank darstellt, wobei die einzelnen Schritte durchnummeriert sind, damit wir uns im Text besser darauf beziehen k&ouml;nnen (auch in den folgenden Listings taucht diese Nummerierung auf).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/Versionierung_opt.jpeg\" alt=\"Versionierung.emf\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 3: Ablauf beim Verkn&uuml;pfen und Updaten des Backends durch ein neues Frontend<\/span><\/b><\/p>\n<p>Im ersten Schritt (1) liest die Routine aus Listing 1 &uuml;ber die Hilfsfunktion <b>GetCurrentBackendPath <\/b>(s. Listing 2) den Pfad und den Dateinamen des Backends aus, auf den sich die im Frontend enthaltenen Tabellenverkn&uuml;pfungen beziehen.<\/p>\n<p class=\"tabellenkopf\">Listing 1: Die Routine StartDB steuert das Update des Backends und die Pr&uuml;fung und Aktualisierung der Tabellenverkn&uuml;pfungen.<\/p>\n<pre>Const cStrVersionTable = &quot;tbl_VersionBE&quot;\r\nPublic Function StartDB()\r\n    Dim dbFrontend As DAO.Database, dbBackend As DAO.Database\r\n    Dim strBackendpath As String\r\n    Dim bolBackendFound As Boolean, bolTablesExist As Boolean, bolStartSuccessful As Boolean\r\n    Dim strOldVersion As String, strNewVersion As String, strCurrentVersion As String\r\n    Set dbFrontend = CurrentDb\r\n    GetCurrentBackendPath dbFrontend, cStrVersionTable, strBackendpath\r\n    On Error Resume Next\r\n    bolBackendFound = Len(Dir(strBackendpath)) &gt; 0\r\n    On Error GoTo 0\r\n    If bolBackendFound = False Then\r\n        strBackendpath = dbFrontend.OpenRecordset(&quot;SELECT Optionvalue FROM tblOptions_Backend &quot; _\r\n        &amp; &quot;WHERE Optionname = &apos;Backendpath&apos;&quot;).Fields(0)\r\n        On Error Resume Next\r\n        bolBackendFound = Len(Dir(strBackendpath)) &gt; 0\r\n        On Error GoTo 0\r\n    End If\r\n    Do While bolTablesExist = False\r\n        Do While bolBackendFound = False\r\n            strBackendpath = OpenFileName(Left(strBackendpath, InStrRev(strBackendpath, &quot;\\&quot;)), _\r\n            &quot;Backend ausw&auml;hlen&quot;, &quot;Access 2007-Datenbank (*.accdb)|Access 2003 und &auml;lter-Datenbank &quot; _\r\n            &amp; &quot;(*.mdb)|Alle Dateien (*.*)&quot;)\r\n            If Len(strBackendpath) = 0 Then Exit Function\r\n            bolBackendFound = Len(Dir(strBackendpath)) &gt; 0\r\n        Loop\r\n        Set dbBackend = OpenDatabase(strBackendpath)\r\n        If CheckTables(dbFrontend, dbBackend, True) = True Then\r\n            strOldVersion = dbBackend.OpenRecordset(&quot;SELECT Version FROM tbl_VersionBE&quot;).Fields(0)\r\n            strNewVersion = dbFrontend.OpenRecordset(&quot;SELECT NeueVersion FROM tblVersionen &quot; _\r\n            &amp; &quot;ORDER BY ReihenfolgeID DESC&quot;).Fields(0)\r\n            Do While Not strCurrentVersion = strNewVersion\r\n                If UpdateVersion(dbFrontend, dbBackend, strOldVersion, strCurrentVersion) = True Then\r\n                    strOldVersion = strCurrentVersion\r\n                Else\r\n                    MsgBox &quot;Das Update wurde nicht durchgef&uuml;hrt.&quot;\r\n                    Exit Function\r\n                End If\r\n            Loop\r\n            bolTablesExist = CheckTables(dbFrontend, dbBackend, False) = True\r\n        Else\r\n            bolBackendFound = False\r\n        End If\r\n        If bolTablesExist = False Then\r\n            If MsgBox(&quot;In der Datenbank &apos;&quot; &amp; strBackendpath &amp; &quot;&apos; fehlen eine oder mehrere der ben&ouml;tigten &quot; _\r\n            &amp; &quot;Tabellen.&quot; &amp; vbCrLf &amp; vbCrLf &amp; &quot;Klicken Sie auf &apos;OK&apos;, um eine andere Datenbank &quot; _\r\n            &amp; &quot;auszuw&auml;hlen oder auf &apos;Abbrechen&apos;, um die Anwendung zu beenden.&quot;, _\r\n            vbOKCancel + vbExclamation, &quot;Falsche Datenbank&quot;) = vbCancel Then\r\n            DoCmd.Quit\r\n            Exit Function\r\n        End If\r\n    End If\r\nLoop\r\nIf ReconnectBackend(dbFrontend, strBackendpath) = True Then\r\n dbFrontend.Execute &quot;UPDATE tblOptions_Backend SET Optionvalue = &apos;&quot; &amp; strBackendpath _\r\n    &amp; &quot;&apos; WHERE Optionname = &apos;Backendpath&apos;&quot;, dbFailOnError\r\n    bolStartSuccessful = True\r\nEnd If\r\nEnd Function<\/pre>\n<p class=\"kastentabelleheader\">Listing 2: Die Funktion GetCurrentBackendPath ermittelt die Datenbank, mit der die Tabellenverkn&uuml;pfungen aktuell verkn&uuml;pft sind.<\/p>\n<pre>Public Function GetCurrentBackendPath(dbFrontend As _\r\n    DAO.Database, strTable As String, _\r\n    strBackendpath As String) As Boolean\r\n    Dim strTemp As String\r\n    strTemp = dbFrontend.TableDefs(strTable).connect\r\n    strTemp = Mid(strTemp, InStr(1, strTemp, &quot;DATABASE=&quot;) + 9)\r\n    If InStr(1, strTemp, &quot;;&quot;) &gt; 0 Then\r\n        strTemp = Left(strTemp, InStr(1, strTemp, &quot;;&quot;) - 1)\r\n    End If\r\n    If Not Len(strTemp) = 0 Then\r\n        strBackendpath = strTemp\r\n        GetCurrentBackendPath = True\r\n    End If\r\nEnd Function<\/pre>\n<p><!--30percent--><\/p>\n<p>Dazu ist noch kein Kontakt mit dem Backend erforderlich; die Information wird per DAO &uuml;ber die <b>Connect<\/b>-Eigenschaft einer der Tabellenverkn&uuml;pfungen ermittelt (siehe weiter hinten unter <b>Aktuelle Backend-Datenbank ermitteln<\/b>).<\/p>\n<p>Hier gibt es zwei M&ouml;glichkeiten, die in (2) gepr&uuml;ft werden. Dabei testet die Routine mit der <b>Dir<\/b>-Funktion, ob die f&uuml;r die Verkn&uuml;pfung angegebene Datei &uuml;berhaupt existiert, und findet eines der folgenden beiden Ergebnisse vor:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Das Frontend wurde soeben als Update &uuml;ber das bestehende Frontend kopiert. Dann zeigen die Tabellenverkn&uuml;pfungen noch auf die Backenddatenbank, die der Entwickler verwendet hat &#8211; es geht bei (3) weiter.<\/li>\n<li class=\"aufz-hlung\">Das Update ist bereits erfolgt. Dann sind die Tabellenverkn&uuml;pfungen bereits auf das Backend beim Benutzer eingestellt und eine erneute Auswahl des Backends entf&auml;llt. M&ouml;glicherweise stimmt der Pfad des Backends auf dem Entwicklersystem auch gleich mit dem Pfad beim Benutzer &uuml;berein oder der Entwickler passt den Pfad vor der Weitergabe entsprechend an &#8211; in diesem Fall geht bei (4) weiter.<\/li>\n<\/ul>\n<p>Wenn die in den Tabellenverkn&uuml;pfungen angegebene Datenbankdatei nicht vorhanden ist, schaut die Routine in eine spezielle Tabelle namens <b>tblOptions_Backend<\/b>, die den Pfad des zuletzt verwendeten Backends speichert, aber auch durch den Entwickler auf einen Pfad voreingestellt werden kann (3). Dies bietet die M&ouml;glichkeit, ein Frontend, das auf mehreren Rechnern des Kunden installiert werden und auf das gleiche, auf einem Server liegende Backend zugreifen soll, direkt auf dieses einzustellen.<\/p>\n<p>Im n&auml;chsten Schritt (5) pr&uuml;ft die Routine den Wert der Boolean-Variablen <b>bolTablesExist<\/b>, die erst den Wert <b>True <\/b>erh&auml;lt, wenn alle Tabellen vorhanden und verkn&uuml;pft sind &#8211; und dies ist beim Einstieg in die Routine noch nicht der Fall. Also geht es nun weiter zu (6), wo erneut eine Pr&uuml;fung erfolgt, ob die zuvor ermittelte Datei &uuml;berhaupt existiert. Ist das nicht der Fall, stimmt also auch der in der Tabelle <b>tblOptions_Backend <\/b>gespeicherte Wert nicht oder dieser ist leer. Dann muss der Benutzer in den sauren Apfel bei&szlig;en und das Backend mit einem <b>Datei &ouml;ffnen<\/b>-Dialog selbst ausw&auml;hlen (7). Dieses Spiel wiederholt sich so lange, bis der Benutzer eine vorhandene Datenbankdatei ausgew&auml;hlt hat.<\/p>\n<p>Ist dies geschehen, hei&szlig;t dies noch lange nicht, dass er auch die richtige Datenbank gew&auml;hlt hat &#8211; es kann ja auch irgendeine Access-Datei sein. Also pr&uuml;ft die Routine im n&auml;chsten Schritt (8), ob die gefundene Datenbank eine Tabelle namens <b>tbl_VersionBE <\/b>enth&auml;lt, und liest deren Wert gegebenenfalls ein. Ist diese Tabelle nicht vorhanden, kann der Benutzer sich entscheiden, ob er ein anderes Backend ausw&auml;hlen (Schritte 9-10-11-5-6-7) oder die Anwendung beenden m&ouml;chte (Schritte 9-10-11-12).<\/p>\n<p>Die Pr&uuml;fung auf die Tabelle <b>tbl_VersionBE <\/b>&uuml;bernimmt &uuml;brigens die Funktion <b>CheckTables<\/b>, die wir weiter hinten unter <b>Tabellenverkn&uuml;pfungen pr&uuml;fen <\/b>beschreiben.<\/p>\n<p>Ist die Tabelle <b>tbl_VersionBE <\/b>vorhanden (9), geht es mit Schritt 13 weiter, in dem die Routine pr&uuml;ft, ob das Backend in der aktuellen Version vorliegt. Hier kommt eine weitere Tabelle ins Spiel, die f&uuml;r diese L&ouml;sung unabdingbar ist: die Tabelle <b>tblVersionen<\/b>. Die Tabelle enth&auml;lt die in Bild 4 erkennbaren Felder, von denen zu diesem Zeitpunkt das Feld <b>NeueVersion <\/b>des letzten Datensatzes interessant ist &#8211; es enth&auml;lt die aktuelle Versionsnummer. Diese vergleicht die Routine <b>StartDB <\/b>mit dem aus der Tabelle <b>tbl_VersionBE <\/b>des Backends gewonnenen Wert und beginnt mit dem Update des Backends, wenn sich beide Werte unterscheiden. <\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/pic003_opt.jpeg\" alt=\"pic003.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 4: Versionsinformationen<\/span><\/b><\/p>\n<p><b>Backend updaten<\/b><\/p>\n<p>Dazu ruft sie die Funktion <b>UpdateVersion <\/b>auf, die weiter hinten unter <b>Backend aktualisieren <\/b>genauer beschrieben wird &#8211; und zwar zun&auml;chst einmal. Dabei durchl&auml;uft diese Funktion alle Datens&auml;tze der n&auml;chsten f&uuml;r das Update wichtigen Tabelle, n&auml;mlich <b>tblVersionUpdates <\/b>aus Bild 5, deren Feld <b>VersionID <\/b>mit dem Prim&auml;rschl&uuml;sselfeld des aktuellen Datensatzes der Tabelle <b>tblVersionen <\/b>&uuml;bereinstimmt, und f&uuml;hrt die im jeweiligen Datensatz enthaltene SQL-Anweisung zum Anpassen des Backends aus. Nach dem Updateschritt schreibt die Routine noch die neue Version in die Tabelle <b>tbl_VersionBE<\/b> im Backend und liefert eine Erfolgsmeldung an die aufrufende Routine <b>StartDB <\/b>zur&uuml;ck &#8211; und die Nummer der neuen Version des Backends (15).<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/pic004_opt.jpeg\" alt=\"pic004.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 5: SQL-Anweisungen, die beim Update auf eine neue Version durchgef&uuml;hrt werden sollen<\/span><\/b><\/p>\n<p>Diese schnappt sich die neue Backendnummer und pr&uuml;ft, ob das Backend nun auf dem aktuellsten Stand ist (13). Falls nicht, ruft sie die Funktion <b>UpdateVersion <\/b>so oft auf, bis keine weiteren Updates mehr vorliegen.<\/p>\n<p>Durch diese schrittweise Einf&uuml;hrung neuer Versionen kann man die Anwendung bei Kunden mit verschiedensten Versionsst&auml;nden mit ein und demselben Frontend auf den aktuellen Stand bringen.<\/p>\n<p><b>Alle Verkn&uuml;pfungen pr&uuml;fen<\/b><\/p>\n<p>Irgendwann hat <b>StartDB <\/b>alle neuen Versionsst&auml;nde auf das Backend &uuml;bertragen und f&auml;hrt mit (14) fort, indem es schlie&szlig;lich alle aktuell im Frontend befindlichen Tabellenverkn&uuml;pfungen dahingehend pr&uuml;ft, ob die referenzierten Tabellen im Backend liegen. Ist das der Fall, wird der Wert <b>bolTablesExist <\/b>auf <b>True <\/b>eingestellt und &uuml;ber (17) erneut (5) angesteuert, wo nun nach (18) weiterverzweigt wird, was im Aktualisieren aller Verkn&uuml;pfungen und dem Beenden der Routine <b>StartDb <\/b>resultiert. Daf&uuml;r ist die Funktion <b>ReconnectBackend <\/b>zust&auml;ndig, die weiter hinten unter <b>Verkn&uuml;pfungen aktualisieren <\/b>beschrieben wird.<\/p>\n<p>Vielleicht ergibt sich in (17) auch, dass die Backenddatenbank nicht alle ben&ouml;tigten Tabellen enth&auml;lt, wodurch der Benutzer die Gelegenheit erh&auml;lt, den Vorgang abzubrechen (11-12) oder ein anderes Backend auszuw&auml;hlen (11-5-6-7).<\/p>\n<p><b>L&ouml;sung einsetzen<\/b><\/p>\n<p>Um diese L&ouml;sung einzusetzen, f&uuml;gen Sie dem Frontend Ihrer Datenbank die Tabellen <b>tblOptions_Backend<\/b>, <b>tblVersionen<\/b>, <b>tblVersionUpdates <\/b>und dem Backend die Tabelle <b>tbl_VersionBE <\/b>hinzu. Au&szlig;erdem geh&ouml;ren die Formulare <b>frmVersionen <\/b>und <b>sfmVersionen <\/b>sowie das Modul <b>mdlGlobal <\/b>in das Frontend. Im Formular <b>frmVersionen <\/b>stellen Sie die Informationen zu den einzelnen Versionen sowie die damit vorzunehmenden &auml;nderungen der Backendtabellen zusammen (siehe Bild 6). In der Praxis gehen Sie, ausgehend beispielsweise von einer Version 0.903, so vor:<\/p>\n<p><img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2009_02\/Versionierung-web-images\/pic005_opt.jpeg\" alt=\"pic005.png\" \/><\/p>\n<p><b><span style=\"color:darkgrey\">Bild 6: Eingeben der Versionsinformationen samt Update-SQL-Anweisungen<\/span><\/b><\/p>\n<ul>\n<li class=\"aufz-hlung\">Eintragen des neuen Versionsdatensatzes und der &auml;nderungen am Backend mithilfe des Formulars <b>frmVersionen <\/b>in die Tabellen <b>tblVersionen <\/b>und <b>tblVersionUpdates<\/b>.<\/li>\n<li class=\"aufz-hlung\">Kopieren der aktuellen Version des Backends, um den alten Zustand wiederherstellen zu k&ouml;nnen.<\/li>\n<li class=\"aufz-hlung\">Aufruf der Funktion <b>StartDB <\/b>und somit Durchf&uuml;hren der &auml;nderungen am Backend.<\/li>\n<li class=\"aufz-hlung\">Im Backend pr&uuml;fen, ob die &auml;nderungen erfolgreich waren.<\/li>\n<li class=\"aufz-hlung\">Wenn neue Tabellen im Backend angelegt wurden, entsprechende Tabellenverkn&uuml;pfungen im Frontend anlegen.<\/li>\n<li class=\"aufz-hlung\">Die alte Version des Backends &uuml;ber die zuvor angefertigte Kopie wiederherstellen und den Ablauf von <b>StartDB<\/b> bei vorhandenen neuen Tabellenverkn&uuml;pfungen testen.<\/li>\n<li class=\"aufz-hlung\">Wenn es bereits fr&uuml;here Versionen gibt, auch deren Update mithilfe der neuen Version des Frontends pr&uuml;fen.<\/li>\n<\/ul>\n<p>Fertig &#8211; wenn alles funktioniert, ist das neue Frontend samt Mechanismen zum Updaten des Backends auslieferungsbereit. Die nachfolgenden Abschnitte beschreiben die verwendeten Hilfsfunktionen der Funktion <b>StartDB<\/b>.<\/p>\n<p><b>Aktuelle Backend-Datenbank ermitteln<\/b><\/p>\n<p>Die Funktion <b>GetCurrentBackendPath <\/b>ermittelt die Eigenschaften der Tabellenverkn&uuml;pfung f&uuml;r eine bestimmte Tabelle. Sie hat drei Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>dbFrontend<\/b>: Verweis auf das <b>Database<\/b>-Objekt des Frontends, also der aktuellen Datenbank<\/li>\n<li class=\"aufz-hlung\"><b>strTable<\/b>: Name der Tabellenverkn&uuml;pfung<\/li>\n<li class=\"aufz-hlung\"><b>strBackendpath<\/b>: R&uuml;ckgabeparameter, der den ermittelten Pfad enth&auml;lt<\/li>\n<\/ul>\n<p>Die Routine liest zun&auml;chst die kompletten Verkn&uuml;pfungseigenschaften aus der <b>Connect<\/b>-Eigenschaft des <b>TableDef<\/b>-Objekts zur angegebenen Tabellenverkn&uuml;pfung aus.<\/p>\n<p>Dieser Ausdruck sieht etwa so aus:<\/p>\n<pre>;DATABASE=E:\\...\\Versionierung_Data.accdb<\/pre>\n<p>Die Funktion <b>GetCurrentBackendPath <\/b>entfernt alle Teile bis auf den Pfad und den Dateinamen und liefert im R&uuml;ckgabeparameter <b>strBackendpath <\/b>nur diese Information zur&uuml;ck.<\/p>\n<p><b>Tabellenverkn&uuml;pfungen pr&uuml;fen<\/b><\/p>\n<p>Die Funktion <b>CheckTables<\/b> (s. Listing 3) erwartet drei Parameter:<\/p>\n<p class=\"kastentabelleheader\">Listing 4: Die Funktion UpdateVersion aktualisiert das Backend von einer Version zur n&auml;chsten.<\/p>\n<pre>Public Function UpdateVersion(dbFrontend As DAO.Database, _\r\n    dbBackend As DAO.Database, strOldVersion As String, _\r\n    strNewVersion As String) As Boolean\r\n    Dim rstVersions As DAO.Recordset\r\n    Dim rstVersionUpdates As DAO.Recordset\r\n    Dim cnn As ADODB.Connection\r\n    Dim strCnn As String\r\n    Dim strSQL As String\r\n    Dim lngRecordsAffected As Long\r\n    Set rstVersions = dbFrontend.OpenRecordset(&quot;SELECT * FROM &quot; _\r\n    &quot;tblVersionen WHERE AlteVersion = &apos;&quot; &amp; strOldVersion _\r\n    &amp; &quot;&apos;&quot;, dbOpenDynaset)\r\n    strNewVersion = rstVersions!NeueVersion\r\n    Set rstVersionUpdates = dbFrontend.OpenRecordset(&quot;SELECT * &quot; _\r\n    &amp; &quot;FROM tblVersionUpdates WHERE VersionID = &quot; _\r\n    &amp; rstVersions!ID &amp; &quot; ORDER BY ReihenfolgeID&quot;, dbOpenDynaset)\r\n    Do While Not rstVersionUpdates.EOF\r\n        strSQL = rstVersionUpdates!SQLAnweisung\r\n        On Error Resume Next\r\n        dbBackend.Execute strSQL, dbFailOnError\r\n        On Error GoTo 0\r\n        If Not Err.Number = 0 Then\r\n            Exit Function\r\n        End If\r\n        rstVersionUpdates.MoveNext\r\n    Loop\r\n    dbBackend.Execute &quot;UPDATE tbl_VersionBE SET Version = &apos;&quot; _\r\n    &amp; strNewVersion &amp; &quot;&apos;&quot;, dbFailOnError\r\n    Set cnn = Nothing\r\n    UpdateVersion = True\r\nEnd Function<\/pre>\n<ul>\n<li class=\"aufz-hlung\"><b>dbFrontend<\/b>: Verweis auf die Frontend-Datenbank<\/li>\n<li class=\"aufz-hlung\"><b>dbBackend<\/b>: Verweis auf die Backend-Datenbank<\/li>\n<li class=\"aufz-hlung\"><b>bolCheckVersion<\/b>: Boolean-Wert, der angibt, ob alle Tabellenverkn&uuml;pfungen gepr&uuml;ft werden sollen (<b>False<\/b>) oder nur eine, und zwar die in der Konstanten <b>cStrVersionTable <\/b>angegebene, in diesem Fall <b>tbl_VersionBE <\/b>(<b>True<\/b>)<\/li>\n<\/ul>\n<p>Die Routine &ouml;ffnet eine Datensatzgruppe auf Basis der Systemtabelle <b>MSysObjects<\/b>, die eine Auflistung aller Tabellenverkn&uuml;pfungen des Frontends enth&auml;lt, und eine weitere Datensatzgruppe, die alle Tabellen aus dem Backend repr&auml;sentiert. Die Routine pr&uuml;ft f&uuml;r alle Datens&auml;tze der ersten Datensatzgruppe, ob es in der zweiten Datensatzgruppe entsprechende Partner gibt &#8211; also die eigentlichen Tabellen zu den Tabellenverkn&uuml;pfungen im Frontend. Ist dies der Fall, gibt die Funktion den Wert <b>True <\/b>zur&uuml;ck.<\/p>\n<p>Wenn der Parameter <b>bolCheckVersion <\/b>den Wert <b>True <\/b>enth&auml;lt, untersucht die Funktion nur die in der Konstanten <b>cStrVersionTable <\/b>angegebene Tabellenverkn&uuml;pfung, sonst alle Tabellenverkn&uuml;pfungen des Frontends.<\/p>\n<p><b>Backend aktualisieren<\/b><\/p>\n<p>Die Funktion <b>UpdateVersion<\/b> (s. Listing 4) erwartet die folgenden Parameter:<\/p>\n<ul>\n<li class=\"aufz-hlung\"><b>dbFrontend<\/b>, <b>dbBackend<\/b>: Verweise auf die beteiligten Datenbanken<\/li>\n<li class=\"aufz-hlung\"><b>strOldVersion<\/b>: Bestehende Version des Backends<\/li>\n<\/ul>\n<p>Au&szlig;erdem liefert sie mit dem Parameter <b>strNewVersion <\/b>die Versionsbezeichnung der Version zur&uuml;ck, die nach der Durchf&uuml;hrung der Funktion vorliegt.<\/p>\n<p>Die Funktion &ouml;ffnet zun&auml;chst eine Datensatzgruppe, die den Datensatz der Tabelle <b>tblVersionen <\/b>liefert, deren Feld <b>AlteVersion <\/b>den im Parameter <b>strOldVersion <\/b>&uuml;bergebenen Wert enth&auml;lt.<\/p>\n<p>Die Tabelle <b>tblVersionsUpdates <\/b>enth&auml;lt voraussichtlich einen oder mehrere Datens&auml;tze mit SQL-DDL-Anweisungen, die am Datenmodell des Backends durchgef&uuml;hrt werden sollen.<\/p>\n<p>Diese Datens&auml;tze durchl&auml;uft die Funktion in der im Feld <b>ReihenfolgeID <\/b>angegebenen Reihenfolge und f&uuml;hrt die gew&uuml;nschten &auml;nderungen durch, indem sie die SQL-Ausdr&uuml;cke mit der <b>Execute<\/b>-Methode des <b>Database<\/b>-Objekts des Backends ausf&uuml;hrt (<b>dbBackend<\/b>).<\/p>\n<p>Danach schreibt die Routine den Wert des Feldes <b>NeueVersion <\/b>des Datensatzes aus der Tabelle <b>tblVersionen <\/b>in die Tabelle <b>tbl_VersionBE <\/b>und gibt <b>True <\/b>als Ergebnis der Funktion zur&uuml;ck.<\/p>\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Verkn&uuml;pfungen aktualisieren<\/p>\n<p>Die Funktion ReconnectBackend (s. Listing 5) erwartet einen Verweis auf das <b>Database<\/b>-Objekt der Frontend-Datenbank sowie die Angabe des Backend-Pfades als Parameter. Sie durchl&auml;uft alle <b>TableDef<\/b>-Objekte der Frontend-Datenbank und schreibt &uuml;berall dort, wo die Eigenschaft <b>Connect <\/b>gef&uuml;llt ist, einen Ausdruck wie den folgenden in diese Eigenschaft (dies funktioniert &uuml;brigens nur mit Access-Datenbankdateien):<\/p>\n<pre>;DATABASE=E:\\...\\Versionierung_Data.accdb<\/pre>\n<p class=\"zwischen-berschriftquellen\">Zusammenfassung und Ausblick<\/p>\n<p>Ob Sie einen Kunden mit einem oder mehreren Benutzern, viele einzelne Kunden oder auch eine Kombination aus beidem mit Ihrer Software bedienen &#8211; die in diesem Beitrag vorgestellte L&ouml;sung bietet die Grundlage f&uuml;r das Update und das Pr&uuml;fen und Aktualisieren der Tabellenverkn&uuml;pfungen in Ihrer Datenbank. Sicher sind hier und da Anpassungen notwendig, und auch eine Fehlerbehandlung haben wir an dieser Stelle aus Platzgr&uuml;nden ausgespart. Diese werden Sie als professioneller Entwickler selbstverst&auml;ndlich entsprechend der in Ihren Anwendungen vorhandenen Fehlerbehandlung nachr&uuml;sten.<\/p>\n<p class=\"kastentabelleheader\">Listing 3: Die Funktion CheckTables pr&uuml;ft, ob die zu den Tabellenverkn&uuml;pfungen geh&ouml;renden Tabellen im Backend vorliegen.<\/p>\n<pre>Public Function CheckTables(dbFrontend As DAO.Database, dbBackend As DAO.Database, _\r\n    bolCheckVersion As Boolean) As Boolean\r\n    Dim rstFrontend As DAO.Recordset\r\n    Dim rstBackend As DAO.Recordset\r\n    Dim bolTableMissing As Boolean\r\n    Dim strSQL As String\r\n    strSQL = &quot;SELECT Name FROM MSysObjects &quot; &amp; &quot;WHERE Database IS NOT NULL&quot;\r\n    If bolCheckVersion = True Then\r\n        strSQL = strSQL &amp; &quot; AND Name = &apos;&quot; &amp; cStrVersionTable &amp; &quot;&apos;&quot;\r\n    End If\r\n    Set rstFrontend = dbFrontend.OpenRecordset(strSQL)\r\n    Set rstBackend = dbBackend.OpenRecordset(&quot;SELECT Name &quot; &amp; &quot;FROM MSysObjects WHERE Type = 1&quot;)\r\n    Do While Not rstFrontend.EOF\r\n        rstBackend.FindFirst &quot;Name = &apos;&quot; &amp; rstFrontend!Name &amp; &quot;&apos;&quot;\r\n        If rstBackend.NoMatch Then\r\n            bolTableMissing = True\r\n            Exit Do\r\n        End If\r\n        rstFrontend.MoveNext\r\n    Loop\r\n    CheckTables = Not bolTableMissing\r\nEnd Function<\/pre>\n<p class=\"kastentabelleheader\">Listing 5: Die Funktion ReconnectBackend aktualisiert die Tabellenverkn&uuml;pfungen im Frontend.<\/p>\n<pre>Public Function ReconnectBackend(dbFrontend As DAO.Database, strBackendpath As String) As Boolean\r\n    Dim tdf As DAO.TableDef\r\n    Dim i As Integer\r\n    For i = 0 To dbFrontend.TableDefs.Count - 1\r\n        With dbFrontend.TableDefs(i)\r\n        If .connect &lt;&gt; &quot;&quot; Then\r\n            .connect = &quot;;database=&quot; &amp; strBackendpath\r\n            .RefreshLink\r\n        End If\r\n        End With\r\n    Next i\r\n    ReconnectBackend = True\r\nEnd Function<\/pre>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>Versionierung.mdb<\/p>\n<p>Versionierung_Data.mdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/{EB854665-62B3-47DD-887F-FE2B8C07A9E1}\/aiu_662.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wer Software f&uuml;r einen Kunden entwickelt und nicht st&auml;ndig an der Produktiv-Version arbeitet, steht irgendwann vor der Anforderung, die Produktiv-Version gegen die neue Version auszutauschen. Dieser Beitrag zeigt eine M&ouml;glichkeit, ein solches Update ohne Reibungsverluste durchzuf&uuml;hren.<\/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":[66022009,662009,44000035,44000027,44000021],"tags":[],"class_list":["post-55000662","post","type-post","status-publish","format-standard","hentry","category-66022009","category-662009","category-Datenzugriff_programmieren","category-Loesungen","category-Tabellen_und_Datenmodellierung"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Verkn&uuml;pfte Datenbanken updaten - 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\/Verknuepfte_Datenbanken_updaten\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Verkn&uuml;pfte Datenbanken updaten\" \/>\n<meta property=\"og:description\" content=\"Wer Software f&uuml;r einen Kunden entwickelt und nicht st&auml;ndig an der Produktiv-Version arbeitet, steht irgendwann vor der Anforderung, die Produktiv-Version gegen die neue Version auszutauschen. Dieser Beitrag zeigt eine M&ouml;glichkeit, ein solches Update ohne Reibungsverluste durchzuf&uuml;hren.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2020-05-22T22:22:44+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0\" \/>\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=\"20\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Verkn&uuml;pfte Datenbanken updaten\",\"datePublished\":\"2020-05-22T22:22:44+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/\"},\"wordCount\":3198,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/00359f3a84c74fc98adfa76b8b5b86d0\",\"articleSection\":[\"2\\\/2009\",\"2009\",\"Datenzugriff programmieren\",\"L\u00f6sungen\",\"Tabellen und Datenmodellierung\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/\",\"name\":\"Verkn&uuml;pfte Datenbanken updaten - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/00359f3a84c74fc98adfa76b8b5b86d0\",\"datePublished\":\"2020-05-22T22:22:44+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/00359f3a84c74fc98adfa76b8b5b86d0\",\"contentUrl\":\"http:\\\/\\\/vg07.met.vgwort.de\\\/na\\\/00359f3a84c74fc98adfa76b8b5b86d0\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Verknuepfte_Datenbanken_updaten\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Verkn&uuml;pfte Datenbanken updaten\"}]},{\"@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":"Verkn&uuml;pfte Datenbanken updaten - 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\/Verknuepfte_Datenbanken_updaten\/","og_locale":"de_DE","og_type":"article","og_title":"Verkn&uuml;pfte Datenbanken updaten","og_description":"Wer Software f&uuml;r einen Kunden entwickelt und nicht st&auml;ndig an der Produktiv-Version arbeitet, steht irgendwann vor der Anforderung, die Produktiv-Version gegen die neue Version auszutauschen. Dieser Beitrag zeigt eine M&ouml;glichkeit, ein solches Update ohne Reibungsverluste durchzuf&uuml;hren.","og_url":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/","og_site_name":"Access im Unternehmen","article_published_time":"2020-05-22T22:22:44+00:00","og_image":[{"url":"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"20\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Verkn&uuml;pfte Datenbanken updaten","datePublished":"2020-05-22T22:22:44+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/"},"wordCount":3198,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0","articleSection":["2\/2009","2009","Datenzugriff programmieren","L\u00f6sungen","Tabellen und Datenmodellierung"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/","url":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/","name":"Verkn&uuml;pfte Datenbanken updaten - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#primaryimage"},"thumbnailUrl":"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0","datePublished":"2020-05-22T22:22:44+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#primaryimage","url":"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0","contentUrl":"http:\/\/vg07.met.vgwort.de\/na\/00359f3a84c74fc98adfa76b8b5b86d0"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Verknuepfte_Datenbanken_updaten\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Verkn&uuml;pfte Datenbanken updaten"}]},{"@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\/55000662","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=55000662"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000662\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000662"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000662"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000662"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}