none
Mit MySQL verknüpfte DSN-Less Tabelle neu verbinden wird von Access nicht korrekt ausgeführt?

    Frage


  • Hallo,

    ich habe hier folgende Situation: Eine Access Datenbank als Frontend (Access 2003 oder 2007, Programmierung in 2007, als .mde für 2003 oder 2007) in Verbindung mit einem MySQL Server per ODBC als Backend. Das Problem tritt unabhängig vom verwendeten MySQL ODBC Treiber auf (5.1 oder 5.2a). In der Access Datenbank sind einige Tabellen auf den MySQL Server verknüpft. Dies geschieht beim Programmstart per CreateTableDef (wie in http://support.microsoft.com/kb/892490/en-us beschrieben, nur auf den MySQL Server umgesetzt).

    Eingabe im VBA Direktbereich gibt:
    print currentdb().TableDefs("MITARBEITER").Connect
    ODBC;DRIVER={MySQL ODBC 5.2a Driver};SERVER=kmwelx01;DATABASE=pds;USER=rouser;PASSWORD=readonly;OPTION=19515;

    Nun möchte ich per Code die Tabelle unter einem neuen User verbinden, in dem Fall um schreibenden Zugriff zuzulassen. Verkürzt (Optionen sieht mein Code hierzu wie folgt aus:

    Public Function MySQLreconnect(Acc_Tbl As String, SQL_Tbl As String, username As String, password As String)
        Dim td As TableDef
        Dim cnnString As String
        Dim options As String
    
        For Each td In CurrentDb.TableDefs
            If td.Name = Acc_Tbl Then
                CurrentDb.TableDefs.Delete Acc_Tbl
                CurrentDb.TableDefs.Refresh
            End If
        Next
        
        cnnString = "ODBC;DRIVER={MySQL ODBC 5.2a Driver};SERVER=mysqlsrv;DATABASE=db01;UID=" & username & ";PWD=" & password & ";OPTION=19515"
        
        Set td = CurrentDb.CreateTableDef(Acc_Tbl)
        td.Connect = cnnString
        td.SourceTableName = SQL_Tbl
        CurrentDb.TableDefs.Append td
        CurrentDb.TableDefs.Refresh
    
    End Function
    

    Ich rufe dann die Funktion mit den Parametern auf:
    MySQLreconnect "MITARBEITER", "PERSONAL", "rwuser", "pwSec0"

    Die Funktion läuft ohne Fehler durch, jedoch verweist die Verknüpfung auf die Tabelle Mitarbeiter danach wieder auf den Benutzer "rouser". Die Eingabe im Direktbereich zeigt auch genau das selbe an, wie vor dem Reconnect:
    print currentdb().TableDefs("MITARBEITER").Connect
    ODBC;DRIVER={MySQL ODBC 5.2a Driver};SERVER=kmwelx01;DATABASE=pds;USER=rouser;PASSWORD=readonly;OPTION=19515;

    Hat hier vielleicht jemand noch einen Tip, was ich noch ändern kann, damit die Verknüpfung mit dem neuen User auch greift?

    So long,

    Marc

    Mittwoch, 20. März 2013 07:16

Alle Antworten

  • Hallo,
    Public Function MySQLreconnect(Acc_Tbl As String, SQL_Tbl As String, username As String, password As String)
        Dim td As TableDef
        Dim cnnString As String
        Dim options As String
    
        For Each td In CurrentDb.TableDefs
            If td.Name = Acc_Tbl Then
                CurrentDb.TableDefs.Delete Acc_Tbl
                CurrentDb.TableDefs.Refresh
            End If
        Next
    ...    
    

    Ohne getestet zu haben scheint mir ein Punkt trotzdem erwaehnenswert: Du
    verwendest als DB-Objekt immer CurrentDb. Das hat zur Folge, dass jede
    Operation von der vorherigen isoliert ablaeuft, weil CurrentDb immer ein
    neues Objekt liefert. Leg stattdessen eine DB-Variable an und verwende
    diese fuer die TableDef-Operationen:

    Dim Db As DAO.Database
    Set Db = CurrentDb

    For Each td In Db.TableDefs
    usw.

    Gruss - Peter
    Donnerstag, 21. März 2013 00:28
    Moderator
  • Am 20.03.2013 schrieb KM-Support:

    Hat hier vielleicht jemand noch einen Tip, was ich noch ändern kann, damit die Verknüpfung mit dem neuen User auch greift?

    In den Answer Foren habe ich dir einen Tipp gegeben, hast Du den
    umgesetzt?

    Servus
    Winfried


    Connect2WSUS: http://www.grurili.de/tools/Connect2WSUS.exe
    GPO's: http://www.gruppenrichtlinien.de
    Community Forums NNTP Bridge: http://communitybridge.codeplex.com/

    Donnerstag, 21. März 2013 06:11
  • Hallo,

    @Peter: Danke, aber an der Variablen liegt es leider nicht. Das Ergebnis bleibt das gleiche.

    @Winfried: Ich hatte schon in den Answer Foren geantwortet, daß die Anforderung so ist, daß die Schreibrechte einen separten Datenbank User erfordern, also die Tabelle in Abhängigkeit vom am Frontend angemeldeten Benutzer neu verbunden werden muß. Und ich habe auch schon ein DoEvents nach jeder einzelnen Zeile Code ausführen lassen - gleiches Ergebnis.

    Die Verknüpfung auf die Tabelle wird auch tatsächlich gelöscht (db.TableDefs.Delete Acc_Tbl), und wenn ich den Code dort unterbreche gibt es auch keine entsprechende Tabelle im Frontend (in MSysObjects ist die Tabelle dann auch nicht enthalten).

    Nachdem die Verknüpfung wieder erstellt wurde (db.TableDefs.Append td) ist die Tabelle wieder da (inkl. Eintrag in MSysObjects), jedoch mit dem alten "rouser" statt dem neuen "rwuser", mit dem die Verknüpfung eigentlich hätte angelegt werden müssen.

    Wo könnte Access sich die alten Verbindungsdaten "merken" und hier falsch zuordnen?

    So long,

    Marc

    Donnerstag, 21. März 2013 07:06
  • Hallo Marc

    Wenn du zum Zeitpunkt wo du die Tabelle mit dem anderen Benutzer neu einbinden willst bereits eine Verbindung auf die gleiche Datenbank gemacht hast, nimmt Access diese Verbindung.

    Das heisst du kanst nicht gleichzeitig 2 Verbindungen zur gleichen DB mit unterschiedlichen Benutzern offen haben.

    Starte die Anwendung ohne Verbindung zur Datenbank und verbinde die Tabellen neu mit dem neuen User / PW und es wird funktionieren.

    Gruss Markus

    Donnerstag, 21. März 2013 09:52
  • Hallo,
     
    KM-Support wrote:
     
    > @Peter: Danke, aber an der Variablen liegt es leider nicht. Das Ergebnis
    > bleibt das gleiche.
     
    Probier mal, die Tabelle /nicht/ zu loeschen, sondern nur den
    Connect-String neu zu setzen:
     
    td.Connect = cnnString
    td.RefreshLink
     
    Gruss - Peter
     
    --
     
    Donnerstag, 21. März 2013 15:12
    Moderator
  • Hallo,

    ich habe das mal so eingetragen:

        Set db = CurrentDb()
        For Each td In db.TableDefs
            If td.Name = Acc_Tbl Then
                td.Connect = cnnString
                td.RefreshLink
            End If
        Next
    

    Aber das td.RefreshLink ergibt nur einen Laufzeitfehler '3146': ODBC-Aufruf fehlgeschlagen.

    Auf diese Weise kommt der selbe Laufzeitfehler:

        Set db = CurrentDb()
        Set td = db.CreateTableDef(Acc_Tbl)
        td.Connect = cnnString
        td.RefreshLink
    

    Aber wenn Markus recht hat, und ich nicht zur selben ODBC Datenbank zwei verschiedene Benutzeranmeldungen offen haben kann, dann könnte das natürlich das Verhalten erklären. Nur würde das bedeuten, daß ich dann vieles umstricken muß, wenn ich zuerst *alle* Verbindungen zur Datenbank mit dem "rouser" trennen muß, und diese dann unter "rwuser" neu verbinden muß...

    Das werde ich wohl mal in einer Test-DB mit 2 Tabellen durch spielen...

    So long,

    Marc...

    Donnerstag, 21. März 2013 15:36
  • Hallo,
     
    KM-Support wrote:
     
    > ich habe das mal so eingetragen:
    >
    >     Set db = CurrentDb()
    >     For Each td In db.TableDefs
    >         If td.Name = Acc_Tbl Then
    >             td.Connect = cnnString
    >             td.RefreshLink
    >         End If
    >     Next
    >
    > Aber das td.RefreshLink ergibt nur einen Laufzeitfehler '3146': ODBC-Aufruf fehlgeschlagen.
     
    Lies mal die Errors-Collection aus:
     
    For I = 0 To Errors.Count -1
      MsgBox Errors(I)
    Next I
     
    Die letzte Meldung die 3146.
     
    > Auf diese Weise kommt der selbe Laufzeitfehler:
    >
    >     Set db = CurrentDb()
    >     Set td = db.CreateTableDef(Acc_Tbl)
    >     td.Connect = cnnString
    >     td.RefreshLink
     
    Das kann nicht funktionieren, weil der Append fehlt. Macht auch wenig Sinn,
    denn fuer den CreateTableDef/Append brauchst du bereits den richtigen
    Connect. ;-)
     
    > Aber wenn Markus recht hat, und ich nicht zur selben ODBC Datenbank zwei verschiedene
    > Benutzeranmeldungen offen haben kann, dann könnte das natürlich das
    > Verhalten erklären.
     
    Du fuehrst die Prozedur doch beim Oeffnen der DB aus, oder? Siehe
    http://www.donkarl.com?FAQ3.1 . Da steht im Absatz vor dem Code-Beispiel:
    "Im Autoexec-Makro oder beim Öffnen des ersten Formulares kann z.B.
    folgender Code aufgerufen werden:"
     
    Gruss - Peter
     
    --
     
    Donnerstag, 21. März 2013 23:01
    Moderator