Создание кода vba для подключения к удаленному серверу SQL, выполнение хранимой процедуры, которая обновляет таблицу в файле accdb - PullRequest
0 голосов
/ 20 сентября 2018

Извините за текст, пытаясь быть кратким

Мы пытаемся настроить процесс, чтобы наши конечные пользователи (удаленные пользователи на ноутбуках, которые перемещаются между различными сетями), которые используют базы данных доступа, отправлялизапросите к нашему серверу SQL, чтобы тот сервер выполнил хранимую процедуру.Как только этот запрос получен на SQL Server, сервер должен найти серию ожидаемых значений для этого пользователя, а затем выполнить другую хранимую процедуру, чтобы инициировать новую ссылку на вызывающее устройство (в зависимости от того, как оно подключено к Интернету).на этот раз), выполните серию проверок данных на этом компьютере, и если проверки пройдены успешно, они должны обновить данные в таблице на удаленном клиенте, а затем отключиться.

У нас настроены процедуры вызоваи прекрасно работают, когда они выполняются с сервера SQL напрямую с использованием SSMS (например: мы заходим на сервер, на котором работает сервер SQL, а затем используем SSMS для выполнения хранимой процедуры), и если мы оставляем ссылки там, мы можем использовать SSMSчитать / редактировать / изменять любые данные / таблицы в удаленном клиенте.Однако, когда хранимые процедуры вызываются из удаленного клиента, они работают, если только эти хранимые процедуры не пытаются читать / записывать на удаленный связанный сервер (например: хранимые процедуры, которые добавляют и удаляют ссылки на базу данных, работают нормально, но запросы, которые выглядятпри редактировании или удалении данных в удаленной базе данных возвращается ошибка, которая выглядит так, как будто она связана с разрешениями, относящимися к доступу к файлам.

Наша среда: устройства в нашем домене, SQLserver 2017 Express, Windows 10, база данных accdb(2007)

В заключение. Мы пишем код VBA для выполнения удаленной хранимой процедуры SQL Server 2017 Express в нашем домене, чтобы обновить таблицу в той же самой вызывающей базе данных accdb (2007), работающей на компьютере с Windows 10.Результат: мы хотим, чтобы на удаленном компьютере выполнялись только хранимые процедуры на сервере sql, а не для определенных таблиц / представлений как для дополнительной безопасности, так и для эффективности.Т.е. доступ vba говорит, что я онлайн, сервер sql создает ссылку и проверяет наличие обновленных контактов, загрузок и отключения.Процедура создает LinkServer (sp_addlinkedserver), входит в систему (sp_addlinkedsrvlogin), обновляет таблицу (@sql = 'UPDATE'), удаляет ссылку (sp_dropserver). После того, как у нас это получится, мы планируем создать другие хранимые процедуры, которые запрашивают файл accdb и загружаютновые данные на сервер SQL.Мы заблокированы при попытке «ВЫБЕРИТЬ» или «ОБНОВИТЬ» к файлу удаленного доступа через хранимую процедуру в VBA (хранимая процедура работает нормально из интерфейса SSMS).

Итак, на сервере SQL мы в настоящее время имеем

CREATE PROCEDURE [dbo].[SQLserverlastconnect] @p_linkservername nvarchar(max) = null, @p_linkdatasrc nvarchar(max) = NULL
AS
DECLARE @sql NVARCHAR(MAX)

EXEC master.dbo.sp_addlinkedserver @server = @p_linkservername, @srvproduct=N'', @provider=N'Microsoft.ACE.OLEDB.12.0', @datasrc= @p_linkdatasrc
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname = N'<servername>\<instance>', @locallogin = NULL , @useself = N'True';

SET @sql = 'UPDATE ' +  @p_linkservername  + '...tbl_Ref_Local SET  tqs_Data =  ''' + CONVERT(varchar(50),FORMAT(CURRENT_TIMESTAMP, 'yyyy-MM-dd hh:mm:ss')) + ''' WHERE tqs_KeyIdentifier = ''LastConnect'''

EXEC(@sql)

EXEC master.sys.sp_dropserver @p_linkservername,'droplogins'  

В Access 365 у нас есть саб (пробовал много изменений в этом, включая поиск проблем со строкой соединения)

Sub Test()
    Dim connection As Object: Set connection = CreateObject("ADODB.Connection")
    Dim rs As Object: Set rs = CreateObject("ADODB.Recordset")
    With connection
              .ConnectionString = "DRIVER=SQL Server;Server=<servername>\<Instance>;Trusted_Connection=Yes;APP=2007 Microsoft Office system;DATABASE=SixBit;User ID=sa;Password=********" ‘[we tried to remove User ID/Password and only use a trusted connection]
              .CommandTimeout =0
              .Open
    End With
    Set rs = connection.Execute("EXEC dbo.SQLserverlastconnect @p_linkservername = N'Test7', @p_linkdatasrc = N'\\fileserver\Programming\TQS - Client 0.03.22.accdb'")
‘tried this also Set rs = connection.Execute("INSERT INTO [Test7]...[tbl_Ref_Local] ([tqs_KeyIdentifier],[tqs_Data],[tqs_GUID]) VALUES ('t', 't' ,'t')")
    connection.Close: Set rs = Nothing: Set connection = Nothing
End Sub

Вещи, которые мы пробовали: Мы добавили всех кОбщая сетевая папка, в которой находится файл, добавила всех к временному пути, Изменила службу SQL-сервера «Вход в систему» ​​со значения по умолчанию на администратора домена, а также «Сетевую службу».Одна область, которую мы не потратили так много времени, - это «сопоставления входа» в свойствах связанного сервера на SQL-сервере (мы пытались олицетворять «sa»). Вот текущее сообщение, которое мы получаем при запуске VBA.Попытался настроить NET USE U :, попытался указать на другую базу данных доступа (более старую версию), которая не открыта, так как появляется сообщение о том, что мы не можем открыть базу данных, когда она работает, также попытался текстовый файл.

Наконец, мы создали триггер и можем заставить его запускать SELECT (много кулачков), но не UPDATE или INSERT (грустное лицо), но это может указывать кому-то что-то там.

Кто-нибудь получиллюбой совет?

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Я использую эту подпрограмму для выполнения кода SQL Server (который может быть любым, включая вызовы хранимых процедур) из Access:

Public Sub ExecuteSQLServerCode(SQL As String)

Dim MyAccessDatabase As DAO.Database
Set MyAccessDatabase = CurrentDb()
With MyAccessDatabase.CreateQueryDef("")
    .Connect = CurrentDb.TableDefs("LinkedTable").Connect
    .SQL = SQL
    .ReturnsRecords = False
    .Execute
    .Close
  End With
MyAccessDatabase.Close
Set MyAccessDatabase = Nothing

End Sub

Проблема в том, что в моем случае у меня есть статически связанная таблица дляSQL-сервер, с которого я могу «заимствовать» соединение.

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

В общем, я бы попробовал эти шаги:

  1. Создать «постоянную» ссылку на таблицу в вашей сети с компьютера AD.
  2. Проверить эту ссылку и заставить ее работать удаленно.
  3. Используйте вышеприведенное для проверки выполнения кода SQL Server из Access локально.
  4. Повторите шаг 3, но удаленно.
  5. Попробуйте заменить таблицу с постоянной связью на динамическое связывание локально.
  6. Повторно повторите шаг 5.
0 голосов
/ 20 сентября 2018

Это кажется плохой идеей и подходом к этому решению.

Прежде всего, если клиент запускает Access как эксклюзивный, то Access или SQL-сервер не смогут установить успешную ссылку.

И вы должны убедиться, что SQL-сервер НЕ пытается открыть (связать) эксклюзивную базу данных доступа на стороне клиента.Возможно, когда вы тестировали из SSMS, у вас не было запущенной копии доступа с тем же открытым файлом accDB.Я не посмотрел близко, но я полагаю, что по умолчанию для ссылки сервера на Access является эксклюзивным (это означает, что файл accDB на стороне клиента не может быть открыт, пока клиент Access имеет тот же файл, открытый.

Хуже, если вы обновите какие-либо данныечерез сторону SERVER в клиенте, тогда любая строка будет перетащена на сервер sql, обновлена ​​и затем отправлена ​​обратно по проводам. Почему бы не переместить этот код обновления локально, и вы НЕ генерируете сетевой трафик для достижения этого обновления локальных данных.

Такие обновления через «wan», а не по локальной сети, ОЧЕНЬ медленные. Пока вы используете систему обновления SQL, вы на самом деле «сырые» чтения данных из локального файла, и этоОЧЕНЬ плохая идея по WAN-соединению. Если вы испытываете разрыв в соединении, вы собираетесь повредить и взорвать локальный файл accDB.

Связанные таблицы из Access to sql server в порядке, так как «файл»не читается и не передается по сети. Однако подключение SQL-сервера к локальному клиенту accDB означает, что выигрышФайловая система dows проходит через SQL-сервер через это соединение VPN / WAN.Вы действительно хотите этого избежать.Это означает, что SQL-сервер выполняет открытие файла, и файловые буферы вдов и чтение происходит на стороне сервера.Ядро ole jet / ace работает на стороне сервера, но чтение файла происходит на стороне клиента.

Я объясняю, почему это большая проблема «порчи» в моей статье:

http://www.kallal.ca/Wan/Wans.html

Кроме того, «модель» и «идея» связанных серверов на самом деле не являются моделью для «прыжка и выхода».Таким образом, связанные серверы представляют собой больше «обслуживающий» тип процесса, в котором вы настраиваете связанный сервер, и он вроде остается на месте.

Таким образом, некая многопользовательская система, в которой связывание других обслуживаний (или файла доступа) на лету, на самом деле не является идеей и концепцией связанных серверов.

Также не ясно, что произойдет, когда у вас будет более одного пользователя для такой системы?Я предполагаю, что могут быть созданы разные именованные связанные серверы, но опять же, ваш код t-sql должен работать на «многих» разных связанных серверах.(так что код должен быть изменен).

Это означает, что ваш t-sql ether должен работать для «многих» разных связанных серверов с одним и тем же кодом t-sql, или вы всегда используете одно и то же имя для связанного сервера.Если вы используете то же имя, то один клиент сможет работать.

Чем больше я думаю об этом подходе, тем хуже он становится.

Мне кажется, гораздо более плавный подход заключался бы в том, чтобы Access связывал таблицы с сервером SQL.

Если вы используете аутентификацию домена для подключения к серверу sql, то любой пользователь, скажем, Excel, может с легкостью выполнить некоторые запросы к этому серверу sql, пока ваша VPN активна.То же самое происходит, если они запускают SSMS.

Я бы подумал:

Использовать вход на сервер SQL и, таким образом, авторизованные пользователи не могут извлекать или просматривать данные из этих таблиц в Excel, Access или некоторых другихдругая клиентская программа, которая может легко обращаться к серверу SQL (включая локальный клиент, на котором работает SSMS).

НЕ включайте UID / пароль в связанные таблицы.Это означает, что вам не нужно включать (в текстовом виде) uid / logon, который вы используете для этого процесса.

Непонятно, скрывает ли приложение AccessОн получает доступ к интерфейсу, но даже если по какой-то причине пользователь пропустит интерфейс вашего приложения, он получит сообщение об ошибке, пытаясь открыть существующую связанную таблицу.(Ссылки не будут работать до тех пор, пока ваш код VBA не выполнит простой вход в систему).Наличие «входа» клиента не требует создания каких-либо новых ссылок на стороне клиента (ни на стороне сервера в этом отношении).

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

Если вы используете ссылки со стороны клиента, то вы никогда не откроете файл windows в этой сети (только соединение через сокет ODBC).

Так же, как приложение доступа, разделенное на внешний интерфейс и внутренний интерфейс, может хорошо работать в твердой локальной сети, такая настройка работает очень плохо в WAN + VPN.

В итоге:Вероятно, вы можете заставить вашу настройку работать, но я не рекомендую ее.

Что искать:

Проверить эксклюзивное открытие / использование файла accDB (убедитесь, что доступ незапуск или открытие на стороне клиента файла accDB как эксклюзивного).Если это произойдет, то sql сторона не сможет сделать ссылку на файл.

Проверьте и убедитесь, что при создании ссылки sql на файл accDB с той стороны сервера, на котором сервер sql не пытается выполнить «исключение».(это будет означать, что Access local не может открыть или использовать файл).

Тот факт, что мы уже «проверяем» оба конца на предмет чего-то, что приведет к сбою этой установки, уже является точкой сбоя, а мы (выНадо убедиться, что все сделано правильно.

Как уже отмечалось, я не рекомендую открывать файл Windows в такой сети.

Так что проверьте эксклюзивный выпуск (оба конца).Тем не менее, я бы посмотрел на то, как Access установит соединение на стороне клиента и выполнит sprocЕсли некоторые данные требуются для окончательного обновления и проверки, происходящей в этом sproc, то выполните проверку на стороне сервера, перенаправьте полученные необходимые данные клиенту и затем выполните локальный код для обновления.

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

...