PDA

Vollständige Version anzeigen : Per ODBC angebundene Tabelle nach Server Down wieder zugreifen


cheaptrick
01.06.2012, 09:23
Hallo,

ich habe eine DB, die auf zwei MS SQL Server zugreift bzw. Tabellen dieser Server angebunden hat.
Einer dieser Server ist nur für den Notfall gedacht, falls der Hauptserver ausfällt.
Nun ist mir aufgefallen, dass, wenn der Hauptserver zwischenzeitlich ausfällt, die Tabellen dieses Servers weiterhin nicht angesprochen werden können, da sie weiterhin einen ODBC-Fehler melden.
Ich könnte nun diese Tabellen neu verlinken aber stelle mal die Frage in den Raum, ob so etwas nicht auch automatisch erfolgen kann.

Wenn ja wie?

Gruß

cheapy

Atrus2711
01.06.2012, 09:30
Hi,

es gibt leider m.W. kein Ereignis, das aussagt: "der Server ist gerade weggestorben". Du kannst aber eine "Prüfverbindung" zum Server dauerhaft aufrechterhalten, etwa per Recordset, und regelmäßig (per Form_Timer) gucken, ob die Kiste noch lebt. Wenn nicht, dann Switch auf Reserve-Server.

Die Befehle zum Neueinbinden kennst du? Es klingt so...

cheaptrick
01.06.2012, 11:29
Das mit dem "Wegsterben" des Servers ist nicht das Problem.
Ich bekomme keine automatischen Verbindung zu den Tabellen hin, wenn der Server wieder lebt.
Meine Frage ging dahin, ob es eine Verbindungsart gibt, die dei Tabellenverbindungen automatisch wieder herstellt, wenn der Server wieder lebt.

Atrus2711
01.06.2012, 11:31
Autoamtisch geht da nix. Aber wie erwähnt, kannst du prüfen und reagieren.

Anne Berg
01.06.2012, 11:33
Hallo,

wie merkst du denn dass die Verbindung unterbrochen wurde?
Du könntest auf den Fehler reagieren und die Tabelleneinbindung ernneut ausführen.

cheaptrick
01.06.2012, 12:39
Das wurde wohl seinerzeit so realisiert, dass jedes mal beim Öffnen eines bestimmten UFOs dieser Test durchgeführt wird.

Die Situation ist die, dass ich zwar mit bekomme das der Server wieder da ist aber ich kann trotzdem nicht auf die Tabellen zugreifen.
Die Neuanbindung wird folgendermaßen gemacht:
Function AttachDSNLessTable(stLocalTableName As String, stRemoteTableName As String, stServer As String, stDatabase As String, Optional stUsername As String, Optional stPassword As String)
On Error GoTo AttachDSNLessTable_Err
Dim td As TableDef
Dim stConnect As String

For Each td In CurrentDb.TableDefs
If td.Name = stLocalTableName Then
CurrentDb.TableDefs.Delete stLocalTableName
End If
Next

If Len(stUsername) = 0 Then
'//Use trusted authentication if stUsername is not supplied.
stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDatabase & ";Trusted_Connection=Yes"
Else
'//WARNING: This will save the username and the password with the linked table information.
stConnect = "ODBC;DRIVER=SQL Server;SERVER=" & stServer & ";DATABASE=" & stDatabase & ";UID=" & stUsername & ";PWD=" & stPassword
End If
Set td = CurrentDb.CreateTableDef(stLocalTableName, dbAttachSavePWD, stRemoteTableName, stConnect)
CurrentDb.TableDefs.Append td
AttachDSNLessTable = True
Exit Function

AttachDSNLessTable_Err:

AttachDSNLessTable = False
'MsgBox "AttachDSNLessTable encountered an unexpected error: " & Err.Description

End Function


Das Modul habe ich mal übernommen und es wird immer ohne Username, also mit trusted authentication gearbeitet.
Leider ist es so, dass ich immer einen Fehler bekomme, wenn ich die Tabellen der wiederbelebten DB neu verlinken will. Es geht übrigens auch nicht mit dem Access eigenen internen Tool, was mich etwas stutzig macht.

Atrus2711
01.06.2012, 12:48
Vielleicht das hier:
http://www.ms-office-forum.de/forum/showthread.php?t=273755&highlight=refreshLink

Was für ein Fehler tritt denn auf?

cheaptrick
01.06.2012, 13:00
Das ist die Fehlermeldung:

3146 - ODBC-Aufruf fehlgeschlagen.

Ja und genau die Prozedur die in der von Dir verlinkten Meldung steht (war ja auch meine Meldung) funzt jetzt nicht.
Kann das mit der Version der SQL Server DB zu tun haben?

Ich habe gerade noch mal getestet, auch mit der 2. Version funzt es nicht. :-(

Atrus2711
01.06.2012, 13:04
Moment. Hast du die Lösung am Ende des verlinkten Threads gesehen?

Josef P.
01.06.2012, 13:10
Hallo!

Das Problem ist der interne OCBC-Cache (oder wie auch immer das heißen mag) von Access.

Zum Ausprobieren: vielleicht hilft es bereits, wenn man mit den identischen ODBC-Connectionstring (ich gehe immer von DNS less aus ;)) von den Tabellen eine PT-Abfrage öffnet.

mfg
Josef

cheaptrick
01.06.2012, 13:34
Also auch die Geschichte mit dem Pseudoindex hat nicht geholfen.

Scheint wirklich ein Cache-Problem zu sein, da es "irgendwann" dann wieder geht.

Der Vorschlag mit der PT-Abfrage hat mich leider auch nicht wirklich weiter gebracht.
(Zur PT-Abfrage noch eine Frage: Bekomme ich es irgendwie hin, dass ich nicht jedes mal nach einer DSN gefragt werde? Das nervt!)

Anne Berg
01.06.2012, 13:48
Hallo,

also, ich mach nach dem Delete immer erst ein db.TableDefs.Refresh, möglicherweise nicht grundlos.

Ich würde es auch vorziehen, in dem in #6 gezeigten Code ein Database-Objekt einzusetzen, anstatt mehrfach auf CurrentDB zuzugreifen.
Desweiteren ist die Schleife nicht gerade optimal, zumal sie beim Fund nicht abgebrochen wird, wo doch offensichtlich ein konkreter Tabellenname übergeben wird.

Das wären so meine Gedanken hierzu...

cheaptrick
04.06.2012, 07:40
Hallo Anne,

auch die Verwendung eines Database-Objekts hat das Problem nicht gelöst.
Es scheint wohl irgendwie ein Cache-Problem zu sein, da es nach einigen Minuten dann doch funktioniert.

Hast Du ne Idee, wie ich dem Cache auf die Sprünge helfen kann?

Anne Berg
04.06.2012, 09:26
Bekomme ich es irgendwie hin, dass ich nicht jedes mal nach einer DSN gefragt werde? Du kannst die Verbindungsparameter im SQL-Fenster über die Abfrage-Eigenschaften einstellen.
Hast Du ne Idee, wie ich dem Cache auf die Sprünge helfen kann?Leider nein, aber vielleicht kann Josef noch etwas dazu sagen...

Josef P.
04.06.2012, 10:02
Hallo!

aber vielleicht kann Josef noch etwas dazu sagen...

Ich hatte einmal ein ähnliches Problem. Sobald der PC in den Standby-Modus ging, wurde die Verbinung unterbrochen und nicht wieder aufgebaut.
Das Problem konnte ich beseitigen, indem ich eine neue Verbindung per PT-Abfrage (dynamisch inkl. Connectionstring der Tabellen) erstellte.
Da das aber bei cheaptrick nicht geholfen hat, weiß ich leider auch keinen Rat.
Vielleicht kann man irgendwie den ODBC-Cache löschen. Als ich vor einiger Zeit so etwas suchte, war meine Suche allerdings nicht erfolgreich.

Bekomme ich es irgendwie hin, dass ich nicht jedes mal nach einer DSN gefragt werde?


Wie erstellt du denn die PT-Abfrage?
Du wirst doch eine QueryDef-Objekt verwenden, oder? Dort gibt es die Eigenschaft "Connect", der du den ODBC-Connectionstring übergeben kannst.
Anm.: Ob meine Variante mit DSN auch klappen würde weiß ich nicht. Daher schrieb ich schon im letzten Beitrag "DSN less". ;)

mfg
Josef

cheaptrick
05.06.2012, 07:28
Hallo Josef,

also, meine Verbindungsdaten für die PT-Abfrage sehen so aus:
ODBC;DRIVER=SQL Server;SERVER=MyServer;UID=MyUsername;APP=Microsoft Office 2003;WSID=XXX;DATABASE=MyDatabase;Trusted_Connection=Yes


Aber damit bekomme ich weiterhin den Fehler ODBC-Aufruf fehlgeschlagen, wenn der Server wieder da ist.
Sind die Verbindungsparameter so, wie Du das gemeint hast?

Auch bei dieser Abfrage ist es so, dass sie nach etwa 10 Minuten wieder ein Ergebnis bringt.

Der Ossi
05.06.2012, 08:38
Frage 1:

Du hast also eine Totzeit von 10 Minuten. Kommst du während dieser 10 Minuten mit z.B. dem SQL Server Management Studio auf den Server drauf?

Frage 2:

Hast du mal einen anderen ODBC-Treiber ausprobiert? Ich setzte z.B. nicht den "normalen" ODBC Treiber ein, sondern i.d.R. den Native Client (den gibt es in Version 9 und 10 und muss ggf. erst von MS heruntergeladen und installiert werden). Im Detail verhalten sich beide Treiber auch unterschiedlich, IIRC sollte man bis SQL Server 2005 den 9er und ab 2008 den 10er verwenden.

Hier gibt es eine Übersicht: http://msdn.microsoft.com/de-de/library/bb964722.aspx

Anscheinend gibt es sogar schon einen 10.5er für SQL Server 2008 R2. :)


Beispiel für Native Client 10:

ODBC;DRIVER=SQL Server Native Client 10.0;Description=MeineBeschreibung;SERVER=MeinServer;DATABASE=MeineDatenbank;Tru sted_Connection=Yes;