Подключение внешнего интерфейса многопользовательского доступа к серверной части SQL Server

Спасибо за помощь как всегда!

Я создал базу данных Access, которую мы собираемся распространить среди ~ 100 конечных пользователей. В настоящее время я запускаю пилотную программу для 5 пользователей. Я перенес таблицы на SQL 2014 Server, но в настоящее время серверная часть пилотной программы находится в общей сетевой папке (местоположение им неизвестно). Я распространил интерфейс Access (тип файла accde), сохранив файл в этой общей сети и указав конечным пользователям сохранить копию на своем рабочем столе. Пилот работает нормально, если не чуточку медленно.

Проблема, с которой я столкнулся, заключается в следующем:

Я могу установить соединение ODBC на моем компьютере и могу подключиться к бэкэнду SQL Server через это соединение. Однако я не уверен, как обеспечить моим конечным пользователям доступ к таблицам на сервере. Нужно ли мне создавать имя пользователя для каждого пользователя на сервере и предоставлять им доступ для чтения и записи? Нужно ли мне также создавать ODBC-соединение на каждой машине, на которой мы планируем установить Front End? Я бы предпочел не создавать ODBC-соединение на каждой машине, можно ли это обойти? Спасибо!

Версия для доступа: 2013 г. SQL: 2014 г. Работа над SSMS 2014 г.

-Чарли


person Chuck0185    schedule 21.02.2017    source источник
comment
У вас есть несколько вопросов, и ни один из них не является однозначным. Вам не нужно создавать пользователя базы данных для каждого пользователя приложения, но вы, безусловно, можете, если хотите. Для меня это звучит излишне, но в некоторых случаях имеет смысл. Что касается вопроса о соединении, это зависит от того, как вы создаете соединение в своем коде. Если вам требуется соединение ODBC, то да, вам нужно будет создать его на каждой машине. Я бы предпочел установить соединение напрямую с сервером, поэтому вам это не нужно.   -  person Sean Lange    schedule 21.02.2017


Ответы (3)


Несколько вещей:

Когда вы создаете связанную таблицу, просто используйте ленту для импорта и связи, а затем базу данных ODBC. Просто выберите файл DSN. Причина этого в том, что для доступа по DEFAULT будет использоваться соединение без DSN. Проще говоря, это означает, что когда вы связываете таблицы, вы можете распространять свое приложение на каждую рабочую станцию, и вам не нужно настраивать системный / машинный DSN.

Так что просто имейте в виду, что используйте файл DSN по умолчанию - как только Access создаст ссылку на SQL-сервер, такие ссылки будут без DSN, и вам не потребуется никаких настроек на каждой рабочей станции.

Что касается создания пользователей на SQL сервере? Что ж, скорее всего, в этом нет необходимости, если только вы не хотите какой-то особой безопасности для каждого пользователя. Если вы используете вход в систему через SQL, убедитесь, что во время вышеупомянутого процесса связывания вы «отметили» опцию сохранения пароля. Еще раз, поскольку по умолчанию связанные таблицы не имеют DSN, тогда каждый пользователь фактически будет использовать один и тот же пользователь SQL / пароль, и, таким образом, это будет прозрачно для каждого пользователя (им не нужно будет входить в систему).

Если вы используете проверку подлинности Windows для входа в систему с помощью SQL, то безопасность настраивается с помощью системы Windows, а не сервера SQL. В этом случае каждый пользовательский вход в Windows будет использоваться для управления (разрешения) использования SQL-сервера. Если вы не используете контроллер домена, то вы используете входы в систему с помощью SQL, и, вероятно, будет достаточно только одного входа в систему, который вы используете. Часто даже в корпоративной среде, потому что я не хочу вызывать ИТ-администраторов для каждого входа в систему и получения разрешений на сервер SQL, я все равно ЧАСТО выбираю вход в систему через SQL. Таким образом, «как только» ИТ-администраторы предоставят мне достаточно прав на SQL-сервер, я могу создавать свои собственные входы в систему или просто использовать «один и тот же» вход для всех, и, таким образом, мне не нужно тратить время на то, чтобы беспокоить ИТ-специалистов. близкие.

Несколько дополнительных заключительных моментов: не обращайте внимания на предложения использовать все виды кода ADO и VBA, строки подключения и т. Д. - они не требуются. Фактически, в большинстве случаев вы хотите ИЗБЕЖАТЬ кода ADO в своем приложении. Кроме того, oleDB обесценивается для SQL-сервера (на который, как правило, полагается ADO).

Вы ВСЕГДА хотите разместить имеющуюся у вас клиентскую программу на каждой рабочей станции. Точно так же, как вы устанавливаете Word на каждую рабочую станцию ​​или свои бухгалтерские пакеты, теперь, когда ВЫ разрабатываете программное обеспечение, вы устанавливаете свое программное обеспечение на каждой рабочей станции, как это делалось в ИТ-индустрии за последние 30 лет. Вы, конечно, можете обмениваться данными в общей папке, но вы устанавливаете фактическое приложение (Word, Excel или, в данном случае, ВАШЕ приложение на КАЖДУЮ рабочую станцию. И вы должны скомпилировать accDB в accDE перед любым развертыванием).

Таким образом, вам действительно не нужен какой-либо специальный код при запуске для «подключения» или «связывания» с SQL-сервером, если вы развертываете для таких пользователей в той же сети. Если вы разработчик или консультант «вне офиса», то вам, вероятно, потребуется добавить код при запуске, чтобы повторно связать их с ИХ сервером sql, который, несомненно, будет отличаться от того, который вы разрабатываете вне офиса. Таким образом, потребуется некоторая возможность повторного подключения к «другому» SQL-серверу, отличному от того, на котором вы разрабатываете, если вы не можете разрабатывать на месте, или если SQL-сервер, с которым вы работаете, является «копией» или «тестом». версия используемого фактического производственного SQL-сервера.

person Albert D. Kallal    schedule 22.02.2017
comment
Хотя вы можете вручную связать и обновить все таблицы вручную в единой ситуации, наличие функции, которая повторно связывает все, является обязательным, если вам нужно иметь возможность добавлять / изменять функции. Он позволяет использовать тестовые базы данных, поэтому разработка и тестирование производственной базы данных не выполняется. - person SunKnight0; 23.02.2017
comment
@Albert D. Kallal Что касается распространения внешних интерфейсов, я много лет использую Auto Front End Updater. Он был создан Тони Таузом и доступен здесь autofeupdater.com. - person Alan Fisher; 27.09.2017

Вам не нужно соединение ODBC на каждой машине. Вы можете создать соединение, используя строки подключения ODBC через DoCmd.TransferDatabase. Это постоянно, поэтому вы можете просто выполнить соединение / обновления в своей разрабатываемой копии внешнего интерфейса, и соединение будет существовать и сохраняться в любых копиях конечных пользователей того, что вы делаете.

Вам действительно нужно решить проблему аутентификации. В зависимости от ситуации с безопасностью вы можете создать одного «пользователя базы данных» и указать имя пользователя и пароль для указанного выше соединения. Если вы находитесь в среде AD, вы можете использовать это для аутентификации. Или вы создаете отдельные учетные записи SQL для каждого пользователя или группы пользователей. Независимо от того, что вы делаете, пользователи смогут просматривать и редактировать таблицы, если Access должен иметь для них права на чтение и запись. Вы можете защитить отдельные таблицы, используя представления, чтобы связать их с Access, а не сами таблицы.

Я бы не советовал пользователям делать локальную копию интерфейса. Это делает кошмаром убедиться, что ваши пользователи используют последнюю версию вашего интерфейса. Поощряйте их вместо этого сделать ярлык. Если у вас нет локальных временных таблиц для каждого пользователя или кода, который динамически редактирует формы / отчеты, нет особых причин, чтобы все не использовали один и тот же файл интерфейса. Даже в этом случае создайте пакетный файл развертывания, который создает / перезаписывает внешнюю копию для каждого пользователя.

Пример кода, который ссылается на базу данных SQL-сервера:

Public Sub LoadDatabase()

Dim MyDB As DAO.Database
Set MyDB = CurrentDb
Dim d As DAO.Recordset
Set d = MyDB.OpenRecordset("SELECT TableName FROM tblLinkTables")
d.MoveFirst
Do While Not d.EOF
    DoCmd.DeleteObject acTable, d!TableName
    DoCmd.TransferDatabase acLink, "ODBC Database", "ODBC;Driver={SQL Server};Server=MYSQLSERVERNAME;Database=MyDatabaseName;Uid=DatabaseUser;Pwd=DatabaseUserPassword", acTable, d!TableName, d!TableName, False, True
    d.MoveNext
  Loop
d.Close
Set d = Nothing

End Sub

где список таблиц для связывания существует в локальной таблице с именем tblLinkTables с одним полем TableName для каждой таблицы, которую нужно связать. Это очень упрощенная версия. Тот, который я на самом деле использую, имеет возможность иметь имена локальных таблиц, отличные от имен таблиц SQL, а также связывать представления и создавать для них первичные ключи (необязательно).

person SunKnight0    schedule 21.02.2017
comment
Спасибо SunKnight0, это дает мне некоторое направление. Я начну исследовать параметр DoCmd.TransferDatabase. Это встроено в код VBA? и нужно ли его запускать, как только пользователь откроет базу данных? - person Chuck0185; 21.02.2017
comment
Нет. Вы просто запускаете его один раз, чтобы подключиться к столам. После этого он сохраняет ссылку в файле .accdb и во всех его копиях. Я добавлю к своему ответу упрощенную LoadDatabase функцию. - person SunKnight0; 21.02.2017
comment
Если у меня есть ярлык для внешнего интерфейса, он будет указывать на общий диск, на котором будет находиться интерфейс. Будет ли обработка информации происходить на сервере, на котором находится общий диск (и во внешнем интерфейсе на общем диске)? Это очень медленный сервер, поэтому я подумал, что компьютер пользователя будет работать быстрее. - person Chuck0185; 21.02.2017
comment
Программное обеспечение всегда запускается на компьютере пользователя, независимо от того, где хранится фактический исполняемый файл (в данном случае ваш клиентский интерфейс Access). На файловом сервере обработки не будет. Вся обработка будет производиться на компьютере пользователя (если выполняется во внешнем интерфейсе) или на сервере базы данных (если вы используете представления, хранимые процедуры и функции), пока ваши данные находятся на сервере SQL, а не в файле доступа. - person SunKnight0; 22.02.2017
comment
SunKnight, Спасибо за помощь. Я создал tblLinkTables и заполнил его всеми таблицами в моей базе данных, как вы предложили. Затем я добавил код VBA и связался с таблицами на SQL Server. Он отлично работал с моей машиной. Когда я столкнулся с проблемой, я сохранил файл Access в нашей общей сети и попросил кого-то другого открыть файл и попытаться открыть одну из форм. Они получили следующее сообщение об ошибке: ODBC Call Failed Вы знаете, почему это происходит? - person Chuck0185; 22.02.2017
comment
Возможно, сетевая безопасность или брандмауэр блокируют связь с сервером, или система не может найти SQL-сервер. Вы можете протестировать все это, вручную создав ODBC-соединение с SQL-сервером и протестировав его на соответствующей рабочей станции. - person SunKnight0; 23.02.2017
comment
Мы замечаем, что только машины с установленным SSMS могут подключаться к таблицам. Когда одна из моих коллег пытается открыть форму, подключенную к таблицам на ее машине, она не может этого сделать. Однако, когда она подключается к другому компьютеру, на котором установлен SSMS, она может подключиться. Любая идея? - person Chuck0185; 23.02.2017
comment
Также нам не удалось вручную создать соединение ODBC на ее машине. - person Chuck0185; 23.02.2017
comment
Я предполагаю, что вам не хватает драйвера ODBC для SQL-сервера на машинах, на которых не установлен SSMS. - person SunKnight0; 23.02.2017

Ниже приводится один из примеров того, как вы можете установить соединение с SQL Server. Он поддерживает либо использование доверенного соединения (где пользователю Windows разрешен доступ, либо вы можете указать идентификатор пользователя и пароль, определенные sqlserver).

' The following are some of the parameters the connection will use.
Global gv_DBS_SQLServer                 As ADODB.Connection
Global gvstr_SQLServer_Name             As String
Global gv_SQLServer_DSN                 As String
Global gvstr_SQLServer_Database         As String

'Call the GetConnection Function
' Pass Name of Server; Database Name; Connection Variable; adUseServer; True if using Password; False if not using a Trusted Connection;
' Sample
    If GetConnection(gvstr_SQLServer_Name, gvstr_SQLServer_Database, _
            gv_DBS_SQLServer, adUseServer, True, False) = False Then
        MsgBox "Unable to connect to SQL Server", vbOKOnly, "No Connection"
    End If


Public Function GetConnection(ByVal strDSN As String, _
        ByVal strDatabase As String, _
        ByRef cnLocal As ADODB.Connection, _
        ByVal CursorLoc As CursorLocationEnum, _
        ByVal UsePassword As Boolean, _
        ByVal blnTrusted As Boolean) As Boolean

Dim strConnectString    As String
Dim strDisplay          As String

    On Error GoTo ERROR_HANDLER
    GetConnection = False
Retry_Connection:
    If cnLocal Is Nothing Then Set cnLocal = New ADODB.Connection
    If cnLocal.State = adStateOpen Then
        Debug.Print "Connection already open -- -will not reopen!!"
        GetConnection = True
        GoTo Proc_Exit
    End If
    With cnLocal
        Debug.Print "Use TRUSTED CONNECTION (ABOVE)"
        If blnTrusted = True Then
            strConnectString = "Driver={SQL Server};" & _
                               "Server=" & strDSN & ";" & _
                               "Database=" & strDatabase & ";" & _
                               "Trusted_Connection=yes"
        Else
            strConnectString = "Driver={SQL Server};" & _
                               "Server=" & strDSN & ";" & _
                               "Database=" & strDatabase & ";" & _
                               "User Id=UUUUUUU;Password=" & DecryptString("PPPPPPPP") & ""

            strDisplay = "Driver={SQL Server};" & _
                         "Server=" & strDSN & ";" & _
                         "Database=" & strDatabase & ";" & _
                         "User Id=UUUUUU;Password=PPPPPPP"

        End If

         Debug.Print "Will use Conn String: " & strDisplay
        .ConnectionString = strConnectString
        .CursorLocation = CursorLoc
        .Open
    End With
    GetConnection = True
Proc_Exit:
    Exit Function
ERROR_HANDLER:
    Debug.Print Err.Number & vbCrLf & Err.Description
    Err.Source = "Module_Connect: " 
    DocAndShowError
    Resume Proc_Exit
    Resume Next
    Resume
End Function
person Wayne G. Dunn    schedule 21.02.2017