tw1ggyz
@tw1ggyz

Как вызвать функцию с ms sql сервера из access?

Есть программы на 2013 аксессе. В них прилинкованы таблицы из 2008 ms sql сервера. В программах есть формы, где люди редактируют данные и изменения посредством Update-запросов на прилинкованные таблицы сохраняются на сервер. Проблема в том, что одно из полей должно записываться в зашифрованном виде. Например, человек вводит в форме значение 1342, а записаться оно должно как Lr$k#yi!&

На ms sql сервере есть функции ID_Decrypt, ID_Encrypt (не хранимые процедуры, а, подчеркиваю, скалярные функции), которые как раз и занимаются этим шифрованием. Принимают один параметр типа varchar расшифровывают\шифруют его и возвращают полученное, тоже varchar, значение.

Вопрос в том, как мне применить эти функции к нужному полю в аксессе?

Что я пробовал:
1. Делать в аксессе passthrough update-запрос. В этом случае на незнакомую функцию не ругается, значит видит. Более того, если не дать входной параметр, так и говорит, что нужен параметр;
2. Кодить в VBA через ADO. Использовал штук пять разных вариантов, нагугленных на стековерфлоу, ни один не сработал. Слишком много вариантов и комбинаций внутри них. Кто-то делал через Recordset, кто-то через Command + к этому добавляются разные вариации вызова функции, а-ля "select ID_Decrypt('1234') as res", "exec ID_Decrypt '123'" и иже с ними.

Если может быть у вас завалялся рабочий (т.е. у вас самих он гарантированно работал в похожей ситуации) вариант кода, прошу поделиться.
  • Вопрос задан
  • 1533 просмотра
Решения вопроса 1
tw1ggyz
@tw1ggyz Автор вопроса
Поместил в событие "После обновления" формы следующий код:

Dim qdef As DAO.QueryDef
    Dim id As String
    Dim guest_id As String
    
    'взял из формы номер, который нужно зашифровать, и поместил в переменную
    id = [Forms]![anketa]![Pass_N]
    guest_id = [Forms]![anketa]![gid]
    
    'создал объект "запрос"
    Set qdef = CurrentDb.CreateQueryDef("")
    'поскольку это pass-through запрос, нужно заполнить свойство Connect. Я взял его от одной из прилинкованных таблиц
    qdef.Connect = CurrentDb.TableDefs("dbo_guest_names").Connect
    'мой запрос - на обновление, записей не возвращает
    qdef.ReturnsRecords = False
    qdef.SQL = "UPDATE [hostel].[dbo].[guest_names] " _
        & "SET id = hostel.dbo.IDEncrypt('" & id & "') " _
        & "WHERE guest_id = '" & guest_id & "'"
    qdef.Execute


Соответственно, dbo.IDEncrypt - имя скалярной функции на ms sql server, а hostel - база данных, в которых эта функция находится. Код точно работает, id сохраняется в базу в зашифрованном виде.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@art_karetnikov
Лучший мой проект: Мобильный банк Сбербанка РФ.
Доброго.
В такой постановке: 1 вариант прост и не требует дополнительных телодвижений. Что в нем не нравится, зачем нужен второй?

Меня лично смущает: "к полю в акцессе". А почему, собственно, не сделать stored procedure с параметрами, из акцесса формировать строку, и выполнять вообще всё, а не конкретно апдейт одного поля, на стороне сервера?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы