MS Access zu SQL Server Ansichten verknüpft
-
10-07-2019 - |
Frage
Wir haben ein Problem mit einer Access-Datenbank aktualisieren wir SQL Server als Datenspeicher zu verwenden.
Diese besondere Datenbank Links zu 2 SQL-Datenbanken, so dachte ich, die Dinge zu vereinfachen, haben wir einen Blick in der Hauptdatenbank, die in der sekundären Datenbank zu jeder Tabelle verknüpft. Auf diese Weise Zugang würde nur direkt mit einer SQL-Datenbank müssen reden.
Wenn wir Zugriff auf die Datenbankansichten verknüpfen wir wählen, welche Felder die Primärschlüssel so waren die Ansichten nicht nur lesbar waren. Wir haben Standard-Code, der alle Links aktualisiert, wenn eine Datenbank zur Abholung öffnet alle Änderungen und die verknüpften Ansichten nur lesbar, weil die Primärschlüsselinformationen verloren.
Gibt es eine Möglichkeit die Links Blick auf erfrischende, während die Primärschlüsselinformationen beibehalten?
John
Lösung
Ich habe meine gesamte ODBC-Reconnect-Funktion unten enthalten. Diese Funktion ist mit der Idee ausgesagt, dass ich eine Tabelle namens rtblODBC, die alle Informationen speichern, ich brauche die erneute Verbindung zu tun. Wenn Sie diese Funktion implementieren, werden Sie nicht auf mehrere SQL-Datenbanken sorgen müssen über die Verbindung, wie mit jedem Tisch behandelt sanft wieder angeschlossen werden, um seine eigene Verbindungszeichenfolge mit.
Wenn Sie am Ende bekommen, werden Sie sehen, dass ich DAO verwenden, um die Primärschlüssel mit db.Execute „CREATE INDEX“ & sPrimaryKeyName & „ON“ & sLocalTableName & „(“ & sPrimaryKeyField & „) neu mit primärem;“
Wenn Sie Fragen haben, wenden Sie sich bitte.
Public Function fnReconnectODBC( _
Optional bForceReconnect As Boolean _
) As Boolean
' Comments :
' Parameters: bForceReconnect -
' Returns : Boolean -
' Modified :
' --------------------------------------------------'
On Error GoTo Err_fnReconnectODBC
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim tdf As DAO.TableDef
Dim sPrimaryKeyName As String
Dim sPrimaryKeyField As String
Dim sLocalTableName As String
Dim strConnect As String
Dim varRet As Variant
Dim con As ADODB.Connection
Dim rst As ADODB.Recordset
Dim sSQL As String
If IsMissing(bForceReconnect) Then
bForceReconnect = False
End If
sSQL = "SELECT rtblODBC.LocalTableName, MSysObjects.Name, MSysObjects.ForeignName, rtblODBC.SourceTableName, MSysObjects.Connect, rtblODBC.ConnectString " _
& "FROM MSysObjects RIGHT JOIN rtblODBC ON MSysObjects.Name = rtblODBC.LocalTableName " _
& "WHERE (((rtblODBC.ConnectString)<>'ODBC;' & [Connect]));"
Set con = Access.CurrentProject.Connection
Set rst = New ADODB.Recordset
rst.Open sSQL, con, adOpenDynamic, adLockOptimistic
'Test the recordset to see if any tables in rtblODBC (needed tables) are missing from the MSysObjects (actual tables)
If rst.BOF And rst.EOF And bForceReconnect = False Then
'No missing tables identified
fnReconnectODBC = True
Else
'Table returned information, we don't have a perfect match, time to relink
Set db = CurrentDb
Set rs = db.OpenRecordset("rtblODBC", dbOpenSnapshot)
'For each table definition in the database collection of tables
For Each tdf In db.TableDefs
'Set strConnect variable to table connection string
strConnect = tdf.Connect
If Len(strConnect) > 0 And Left(tdf.Name, 1) <> "~" Then
If Left(strConnect, 4) = "ODBC" Then
'If there is a connection string, and it's not a temp table, and it IS an odbc table
'Delete the table
DoCmd.DeleteObject acTable, tdf.Name
End If
End If
Next
'Relink tables from rtblODBC
With rs
.MoveFirst
Do While Not .EOF
Set tdf = db.CreateTableDef(!localtablename, dbAttachSavePWD, !SourceTableName, !ConnectString)
varRet = SysCmd(acSysCmdSetStatus, "Relinking '" & !SourceTableName & "'")
db.TableDefs.Append tdf
db.TableDefs.Refresh
If Len(!PrimaryKeyName & "") > 0 And Len(!PrimaryKeyField & "") > 0 Then
sPrimaryKeyName = !PrimaryKeyName
sPrimaryKeyField = !PrimaryKeyField
sLocalTableName = !localtablename
db.Execute "CREATE INDEX " & sPrimaryKeyName & " ON " & sLocalTableName & "(" & sPrimaryKeyField & ")WITH PRIMARY;"
End If
db.TableDefs.Refresh
.MoveNext
Loop
End With
subTurnOffSubDataSheets
fnReconnectODBC = True
End If
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
Exit_fnReconnectODBC:
Set tdf = Nothing
Set rs = Nothing
Set db = Nothing
varRet = SysCmd(acSysCmdClearStatus)
Exit Function
Err_fnReconnectODBC:
fnReconnectODBC = False
sPrompt = "Press OK to continue."
vbMsg = MsgBox(sPrompt, vbOKOnly, "Error Reconnecting")
If vbMsg = vbOK Then
Resume Exit_fnReconnectODBC
End If
End Function
Andere Tipps
Ein großer Teil der DSN weniger Code, der den Zugriff erneut Links Tabellen zu SQL Server löscht oft die Links zuerst, dann die Verbindung neu erstellt. Der Code richtet dann die Verbindungszeichenfolge. Somit ist es das Löschen, die Sie verursacht zu verlieren, was der Primärschlüssel war / ist.
ich wirklich empfehlen, dass Sie Ihren Wieder Link-Code zu ändern, um nicht die Tabellenverknüpfungen zu löschen.
Versuchen Sie so etwas wie:
For Each tdfCurrent In dbCurrent.TableDefs
If Len(tdfCurrent.Connect) > 0 Then
If Left$(tdfCurrent.Connect, 5) = "ODBC;" Then
strCon = "ODBC;DRIVER={sql server};" & _
"SERVER=" & ServerName & ";" & _
"DATABASE=" & DatabaseName & ";" & _
"UID=" & UserID & ";" & _
"PWD=" & USERpw & ";" & _
"APP=Microsoft Office 2003;" & _
"WSID=" & WSID & ";"
End If
End If
tdfCurrent.Connect = strCon
tdfCurrent.RefreshLink
End If
Next tdfCurrent
Das funktioniert ein litte besser für mich (das verschobene Ende, wenn die Anmerkung):
Dim dbCurrent As Database
Set dbCurrent = CurrentDb()
StatusList.SetFocus
StatusList.AddItem ("starting... ")
I = DoEvents()
Dim tdfCurrent As DAO.TableDef
For Each tdfCurrent In dbCurrent.TableDefs
If Len(tdfCurrent.Connect) > 0 Then
If Left$(tdfCurrent.Connect, 5) = "ODBC;" Then
strCon = "ODBC;DRIVER={sql server};" & _
"SERVER=" & ServerName & ";" & _
"DATABASE=" & DatabaseName & ";" & _
"UID=" & UserID & ";" & _
"PWD=" & USERpw & ";" & _
"APP=Microsoft Office 2003;" & _
"WSID=" & WSID & ";"
StatusList.AddItem ("fixing " & tdfCurrent.Name)
tdfCurrent.Connect = strCon
tdfCurrent.RefreshLink
End If
End If
I = DoEvents()
Next tdfCurrent
StatusList.AddItem ("----Done.")
Der ODBC-Check ist richtig, auch wenn die "ODBC;" Teil zeigt nicht in der MSysObjects Ansicht.