如何创建一个子窗体MSACCESS数据表与ADO参数化查询或存储过程的记录源更新?(How can

2019-10-29 16:54发布

我有一个窗体设置为数据表视图,我试图从SQL Server数据的基础上,由用户选择指定的参数进行更新。

我通常使用存储过程实现这一点,有VBA调用它们通过ADO,但这个数据是在记录源需要能够加以修正/数据表中直接编辑不同。

我有我目前使用的显示数据的数据表,这个使用下面的代码:

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

可以这样修改,使数据集更新?

这是迄今为止我已经能够达到我想要做的唯一途径,但由于majorly明显的安全和注射的问题,我不希望走这条路线:

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

Answer 1:

你不能。 从存储过程返回记录集不可更新。

当然,你可以使用DAO如果你希望它是可更新的使用参数化查询。

对于如何创建参数化查询,看到这个答案 ,在使用DAO部分。 请注意,我强烈警告反对,我最后一次使用的访问有一些错误在处理上的参数化查询过滤器/排序。

您也可以检查如何通过直通查询做到这一点, 利用ADO部分。

需要注意的是混淆你的SQL服务器地址是徒劳的(可以用平凡的互联网流量分析工具,被发现),因为你似乎不使用加密连接,你目前的其他参数的混淆是平凡的工作太绕。 这可能足以抵挡好奇的用户在SQL Server安全没有经历过,但绝不是真正的安全。

对于更新的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


Answer 2:

这似乎是你的领域ps_dateClaim不是一个时间戳,但日期时间字段,所以尝试使用:

sp.Parameters.Append sp.CreateParameter("@wkEnd", adDate, adParamInput, , wkEnd)


文章来源: How can I create an updateable recordsource for an MSACCESS subform datasheet with a parameterised query or stored procedure in ADO?