Как я могу создать обновляемый источник записей для таблицы данных подчиненной формы MSACCESS с параметризованным запросом или хранимой процедурой в ADO? - PullRequest
0 голосов
/ 16 октября 2019

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

Обычно я достигаю этого с помощью хранимых процедур и имеюVBA вызывает их через ADO, но эти данные отличаются тем, что RecordSource необходимо иметь возможность изменять / редактировать непосредственно в таблице данных.

У меня есть таблица данных, которую я в настоящее время использую для отображения данных, и этоиспользует следующий код:

Dim db As ADODB.Connection
Dim rs As ADODB.Recordset
Dim sp As ADODB.Command

Set db = New ADODB.Connection
Set rs = New ADODB.Recordset
Set sp = New ADODB.Command
Set ps = frmName
    db.Open dbString
    db.CursorLocation = adUseClient

    With sp
        .ActiveConnection = db
        .CommandText = "x04_ch_sl_ptsTable"
        .CommandType = adCmdStoredProc
        .Parameters.Append sp.CreateParameter("@tmName", adVarChar, adParamInput, 4, tmName)
    End With

    sp.Parameters.Append sp.CreateParameter("@wkEnd", adDBTimeStamp, adParamInput, , wkEnd)
        Set rs = sp.Execute
        Set ps.subFormDataViewer.Form.Recordset = rs
        Exit Sub
    End If
db.Close

Можно ли это изменить, чтобы сделать набор данных обновляемым?

Это пока единственный способ, которым я смог добиться того, чего хочу, ноиз-за очевидных проблем с безопасностью и внедрением я не хочу идти по этому пути:

ps.subFormDataViewer.Form.RecordSource = " SELECT p.ps_dateClaim as [Date], p.ps_id as [ID], p.ps_empid as [Employee ID], e.hc_fullName as [Employee], p.ps_pts as [Claimed] " & _
                                            " FROM (([ODBC;DRIVER=SQL Server;SERVER=<REDACTED>;Integrated_Security=SSPI;DATABASE=<REDACTED>].prod_pts as p " & _
                                            " INNER JOIN [ODBC;DRIVER=SQL Server;SERVER=<REDACTED>;Integrated_Security=SSPI;DATABASE=<REDACTED>].hc_employee as e " & _
                                                " ON p.ps_empid = e.hc_empid) " & _
                                            " WHERE (p.ps_dateClaim = #" & wkEnd & "#" & _
                                                " AND (e.hc_teamName = '" & tmName & "'); "

Я пробовал следующие методы ADO безуспешно:

    With sp
        Set .ActiveConnection = db
        .CommandText = " SELECT t.Date, t.TeamName, t.Reference, t.Status, t.Reason, t.Checked " & _
                        " FROM testTbl as t" & _
                        " WHERE t.TeamName = @tmName "
            .Parameters.Append .CreateParameter(, adVarChar, adParamInput, 4, tm)
        Set rs = .Execute
    End With
    With sp
        Set .ActiveConnection = db
        .CommandText = " SELECT t.Date, t.TeamName, t.Reference, t.Status, t.Reason, t.Checked " & _
                        " FROM testTbl as t" & _
                        " WHERE t.TeamName = ? "
        Set rs = .Execute(, Array(tm))
    End With

(2-й пример производит данные, но набор записей не может быть обновлен, поскольку он распознает каждое поле как «выражение»)

Мне удалось этого добитьсяс DAO:

Dim db as DAO.Database
Dim rs as DAO.Recordset
Dim qd as DAO.QueryDef
Dim dbSQL as string

dbSQL = " SELECT t.Date, t.TeamName, t.Reference, t.Status, t.Reason, t.Checked " & _
                        " FROM testTbl as t" & _
                        " WHERE t.TeamName = tmName1 "
Set qd = db.CreateQueryDef("", dbSQL)

With qd
    .Parameters!tmName1 = tm
End With

Set rs = qd.OpenRecordset
Set ps.subFormDataViewer.Form.Recordset = rs

Ответы [ 2 ]

3 голосов
/ 16 октября 2019

Вы не можете. Наборы записей, возвращаемые из хранимых процедур, не подлежат обновлению.

Конечно, вы можете использовать параметризованный запрос с использованием DAO, если вы хотите, чтобы он был обновляемым.

Инструкции по созданию параметризованных запросов см. * 1005. * этот ответ , раздел Using DAO . Обратите внимание, что я настоятельно предупреждаю об этом, когда я в последний раз использовал Access, было несколько ошибок в обработке фильтров / сортировок для параметризованных запросов.

Вы также можете проверить раздел Использование ADO , чтобы узнать, каксделайте это с помощью промежуточного запроса.

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

Для обновляемого набора записей ADO:

With sp
    Set .ActiveConnection = db
    .CommandText = " SELECT t.Date, t.TeamName, t.Reference, t.Status, t.Reason, t.Checked " & _
                    " FROM testTbl as t" & _
                    " WHERE t.TeamName = ?"
        .Parameters.Append .CreateParameter(, adVarChar, adParamInput, 4, tm)
    Dim rs AS ADODB.Recordset
    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseClient
    rs.Open sp, , adOpenDynamic, adLockOptimistic
End Wit
0 голосов
/ 16 октября 2019

Похоже, ваше поле ps_dateClaim является не отметкой времени, а полем DateTime , поэтому попробуйте:

sp.Parameters.Append sp.CreateParameter("@wkEnd", adDate, adParamInput, , wkEnd)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...