Заставить Access забыть имя пользователя и пароль для связанной таблицы - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть база данных MS Access, которая связана с сервером SQL через связанные серверы.

Связанные таблицы добавляются с использованием модифицированной процедуры AttachDSNLessTable:

stConnect = "ODBC;DRIVER=" & stDriverName & ";SERVER=" & stServer & ";DATABASE=" & stDatabase & ";UID=" & stUsername & ";PWD=" & stPassword
Set td = CurrentDb.CreateTableDef(stLocalTableName)
td.SourceTableName = stRemoteTableName
td.Connect = stConnect

CurrentDb.TableDefs.Append td

У меня есть возможность изменить зарегистрированного пользователя в приложении, это удалит все tabledefs:

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

Затем он будет повторно добавлен, используя процедуру выше.

Теперь, похоже, это работает, но если я войду в систему как user1, тогда изменю пользователя на user2 без закрытия. Доступ к соединению осуществляется с использованием учетных данных user1, при этом представление, включающее SUSER_NAME(), показывает user1 зарегистрированный пользователь.

Есть ли способ принудительно сбросить соединение или изменить пользователя?

Редактировать

Моя функция входа в систему:

Function AttachDSNLessTable(stLocalTableName As String, stRemoteTableName As String, stDriverName 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
            Exit For
        End If
    Next

    If Len(stUsername) = 0 Then
        '//Use trusted authentication if stUsername is not supplied.
        stConnect = "ODBC;DRIVER=" & stDriverName & ";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=" & stDriverName & ";SERVER=" & stServer & ";DATABASE=" & stDatabase & ";UID=" & stUsername & ";PWD=" & stPassword
    End If

    Set td = CurrentDb.CreateTableDef(stLocalTableName)
    td.SourceTableName = stRemoteTableName
    td.Connect = stConnect

    CurrentDb.TableDefs.Append td
    AttachDSNLessTable = ""
    Exit Function

AttachDSNLessTable_Err:

    AttachDSNLessTable = err.Description

End Function

Ответы [ 2 ]

0 голосов
/ 15 ноября 2018

Пара идей, чтобы попробовать.Я предлагаю их только потому, что их легко проверить.

  1. Попробуйте сначала переименовать старую таблицу, затем создать новую таблицу, а затем удалить старую.Если вы обманываете Access, думая, что вы добавляете, а не заменяете, он может взаимодействовать.

  2. Попробуйте добавить другой элемент в строку соединения (кроме UID, который Access обрабатывает особым образом)сделать его уникальным для каждого пользователя.Я считаю, что вы можете добавить произвольную пару тег / значение в строку подключения ODBC, и она игнорируется.Например,

    "ODBC;Driver=SQL Server;MyUniqueTag=" & stUserName & ";UID=" & stUserName
    

    Пулы соединений ODBC уникальны для каждой строки соединения, поэтому это может ввести в заблуждение доступ к использованию другого пула соединений, поскольку он не знает, что MyUniqueTag не используется драйвером ODBC.

0 голосов
/ 15 ноября 2018

РЕДАКТИРОВАТЬ

Мне потребовалось время, чтобы понять это.Ваша проблема в том, что Access кэширует соединения на основе {сервер, база данных}.Нет никакого способа очистить этот кеш (насколько я знаю)

Однако есть выход: ответ заключается в том, чтобы сделать соединение уникальным, даже если детали сервера или базы данных не изменились.

Использование файлов DSN Вы не можете изменить имя базы данных или имя сервера, чтобы сделать соединение уникальным, но вы можете изменить имя файла DSN, которое Access будет видеть как «уникальное» / новое соединение.

Если вы используете один и тот же DSN-файл, соединение снова кэшируется, поэтому вы должны использовать разные DSN-файлы для каждой попытки входа в систему.

Вот общая функция, которая позволяет пользователю входить или выходить изваша система.При каждом входе в систему создается новый DNS-файл и устанавливается новое подключение к вашей базе данных =>, позволяя зарегистрированному пользователю быть новым пользователем.

Приведенные ниже функции являются просто концептуальными.Измените в соответствии с вашими потребностями и добавьте атрибуты ошибок.

Public Function FN_CREATE_DNS_FILE()


    Const Server    As String = "" ' Server
    Const Driver    As String = "" ' Driver
    Const Port      As String = "" ' Port
    Const Database  As String = "" ' Database

    Dim DsnFileName As String
    Dim Fso         As Object
    Dim DnsFile     As Object

    Set Fso = CreateObject("Scripting.FileSystemObject")
    DsnFileName = VBA.Environ$("temp") & "\" & VBA.Format(Now(), "yyyy-mm-dd_hh_mm_ss") & ".dsn"

    Set DnsFile = Fso.CreateTextFile(DsnFileName)
    DnsFile.WriteLine "[ODBC]"
    DnsFile.WriteLine "DRIVER=" & Driver
    DnsFile.WriteLine "PORT=" & Port
    DnsFile.WriteLine "DATABASE=" & Database
    DnsFile.WriteLine "SERVER=" & Server

    'Close file and clean up
    DnsFile.Close
    Set Fso = Nothing
    Set DnsFile = Nothing

    FN_CREATE_DNS_FILE = DsnFileName

End Function

Public Function LogOut()

    Dim Qdf         As QueryDef

    For Each Qdf In CurrentDb.QueryDefs
        If (VBA.InStr(Qdf.Connect, "ODBC")) > 0 Then
            Qdf.Connect = "ODBC;" 'Either delete if you don't require this object or set to blank connection string
        End If
    Next Qdf

End Function



Public Function LogIn(stUsername As String, stPassword As String)

    Dim Tdf         As TableDef
    Dim Qdf         As QueryDef
    Dim stConnect   As String
    Dim ConForQuery As String
    Dim I           As Integer: I = 0

    Dim DsnFileName As String

    On Error GoTo AttachDSNLessTable_Err
    'Produce new DNS file with new filename to make Acces Connection unique
    DsnFileName = FN_CREATE_DNS_FILE()

    stConnect = "ODBC;AUTO_RECONNECT=1;NO_PROMPT=1"
    If Len(stUsername) = 0 Then
        '//Use trusted authentication if stUsername is not supplied.
        stConnect = stConnect & ";Trusted_Connection=Yes"
        ConForQuery = stConnect
    Else
        '//WARNING: This will save the username and the password with the linked table information.
        stConnect = stConnect & ";UID=" & stUsername & ";PWD=" & stPassword
        ConForQuery = stConnect & ";UID=" & stUsername
    End If

    ConForQuery = ConForQuery & ";" & "FILEDSN=" & DsnFileName
    stConnect = stConnect & ";" & "FILEDSN=" & DsnFileName

    On Error GoTo ERROR_Invalid_login
    'Update all linked tables
    For Each Tdf In CurrentDb.TableDefs
        If (VBA.InStr(Tdf.Connect, "ODBC")) > 0 Then
            Tdf.Connect = stConnect & ";TABLE=" & Tdf.Name
            If (I = 0) Then Tdf.RefreshLink 'Refreshing one table is enough as long as table definition hasnt changed
            I = I + 1
        End If
    Next Tdf

    'update all passthrough queries
    For Each Qdf In CurrentDb.QueryDefs
        If (VBA.InStr(Qdf.Connect, "ODBC")) > 0 Then
            Qdf.Connect = stConnect
        End If
    Next Qdf

    LogIn = ""
    Exit Function

AttachDSNLessTable_Err:
    LogIn = Err.Description
    Exit Function

ERROR_Invalid_login:
    LogIn = "Login failed"
    LogOut 'Delete or set blank for all pass through queries
End Function

, если пользователь входит в систему, вы просто позвоните

LogIn(Username, password)

, который обновит всесвязанные таблицы, а также сквозные запросы.

Вот скриншот.Different user

QryCurrentUser выполняет команду MySQL select user();, которая показывает владельца текущего соединения.Как видите, каждый логин показывает правильные имена пользователей, вошедших в систему.

Если логин не удался , у вас есть два варианта.Удалить все ссылки в таблицах и сквозные запросы.или установите для них пустую строку подключения.

PS Я добавил NO_PROMPT & AUTO_RECONNECT в строку подключения, которая не позволяет отображать окно подключения к базе данных при сбое входа в систему и автоматически подключается повторно(Команда MySQL, не уверен, работает ли она для MSSQL), если они несовместимы, удалите их.

Дайте мне знать, если вам удалось это сделать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...