SQL ServerビューにリンクされたMS Access
-
10-07-2019 - |
質問
SQL Serverをデータストアとして使用するためにアップグレードするアクセスデータベースに問題があります。
この特定のデータベースは2つのsqlデータベースにリンクしているので、物事を単純化するために、セカンダリデータベースの各テーブルにリンクするメインデータベースにビューがあることを考えました。そうすれば、アクセスは1つのSQLデータベースと直接対話するだけで済みます。
データベースビューへのアクセスをリンクするとき、ビューが読み取り専用ではないように、どのフィールドがプライマリキーであるかを選択します。データベースを開いて変更をピックアップし、主キー情報が失われるためリンクされたビューが読み取り専用になると、すべてのリンクを更新する標準コードがあります。
主キー情報を保持したまま、ビューへのリンクを更新する方法はありますか?
ジョン
解決
以下にODBC再接続機能全体を含めました。この関数は、再接続に必要なすべての情報を格納するrtblODBCというテーブルがあるという考えに基づいています。この関数を実装する場合、複数のSQLデータベースへの接続について心配する必要はありません。これは、独自の接続文字列を持つ再接続される各テーブルでスムーズに処理されるためです。
最後に近づくと、DAOを使用してdb.Execute" CREATE INDEX"で主キーを再作成していることがわかります。 & sPrimaryKeyName& "オン" & sLocalTableName& "("& sPrimaryKeyField&")WITH PRIMARY;"
質問がある場合は、お問い合わせください。
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
他のヒント
アクセステーブルをSQLサーバーに再リンクするDSNを大幅に削減したコードは、多くの場合、最初にリンクを削除してからリンクを再作成します。次に、コードは接続文字列を設定します。したがって、主キーが何であったかを失う原因となるのは削除です。
実際には、テーブルリンクを削除しないように再リンクコードを変更することをお勧めします。
次のようなものを試してください:
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
これは私にとってより良い動作をします(移動した場合の終了に注意してください):
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.")
&quot; ODBC;&quot;にもかかわらず、ODBCチェックは正しいMSysObjectsビューに一部が表示されません。