2009-06-24 7 views
4

우리는 데이터 저장소로 SQL Server를 사용하도록 업그레이드 할 액세스 데이터베이스에 문제가 있습니다.MS 액세스 SQL 서버보기에 연결

이 특정 데이터베이스는 2 개의 SQL 데이터베이스에 연결되므로, 단순화 할 생각으로 기본 데이터베이스에서 보조 데이터베이스의 각 테이블에 연결된 뷰가 있습니다. 그렇게하면 액세스는 하나의 SQL 데이터베이스와 직접 대화하면됩니다.

데이터베이스보기에 대한 액세스를 링크 할 때보기가 읽기 전용이 아닌 기본 키인 필드를 선택합니다. 기본 키 정보가 손실되기 때문에 데이터베이스에서 변경 사항을 가져오고 링크 된 뷰가 읽기 전용이 될 때 모든 링크를 새로 고치는 표준 코드가 있습니다.

기본 키 정보를 유지하면서보기에 대한 링크를 새로 고치는 방법이 있습니까?

+1

어떻게 링크를 새로 고 칩니 까? 또한 - DB 구조 (SQL 서버에서)가 정보를 얻기 위해 액세스하기 위해 자주 변경됩니까? – shahkalpesh

답변

4

: 같은

보십시오 뭔가. 이 함수는 내가 재 연결을하기 위해 필요한 모든 정보를 저장하는 rtblODBC라는 테이블을 가지고 있다고 생각합니다. 이 함수를 구현하면 여러 SQL 데이터베이스에 연결하는 것에 대해 걱정할 필요가 없습니다. 연결 문자열이있는 각 테이블을 다시 연결하기 위해 원활하게 처리되기 때문입니다. 당신이 끝으로 도착하면

당신은 내가 db.Execute와 기본 키를 다시 DAO를 사용하는 것을 볼 수 PRIMARY 함께 & sLocalTableName & "("& sPrimaryKeyField & ")"ON "& sPrimaryKeyName &"INDEX 만들기 "; "

질문이 있으시면 언제든지 문의하십시오.

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 
+0

David, 코드가 tabledef를 추가하려고하면 3264 오류가 발생합니다. John –

+1

David, 약간의 수정이 있었지만, 테이블 용도의 삭제 및 다시 작성 대신 DAO refreshlink를 사용하여 색인을 작성하고 매우 잘 작동합니다. 도움을 주셔서 감사합니다 –

+0

그것이 당신을 위해 일해서 다행입니다. –

1

SQL 서버에 액세스 테이블 - 링크 다시 DSN 적은 코드의 좋은 거래는 종종 다음 링크를 재현 먼저 링크를 삭제합니다. 그러면 코드가 연결 문자열을 설정합니다. 따라서 삭제로 인해 기본 키의 손실이 발생합니다.

실제로 테이블 링크를 삭제하지 않기 위해 재 링크 코드를 수정하는 것이 좋습니다. 내가 아래에있는 내 전체 ODBC 다시 연결 기능을 포함했다

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 
0

이것은 (의 경우 이동 끝을주의) 나를 위해 litte 더 잘 작동 :

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.") 

는 ODBC 검사가 정확에도 불구하고 "ODBC;" 부분은 MSysObjects보기에 표시되지 않습니다.