用户编辑链接的 SQL 服务器 table 通过直通查询的结果过滤

User-editing a linked SQL Server table filtered by the results from a passthrough query

我 运行 MS Access 2016 连接到 SQL 服务器上的链接 table(我认为 2012,如果重要的话),以便允许单个用户(我)快速操作 table 中的数据。我有一个相当密集的传递查询,它创建一个主键值列表,表示 table 中的数据有问题的行(通常只是空值,不应该是空值,但也是无效的组合值和无效日期)。

我想只显示由我的传递查询识别的行,这样我可以快速输入缺失值并进行其他更正。但是,我完全不知道该怎么做。

为了尝试遵循最佳实践,我尝试让相关行以一种只有特定字段为 editable 的形式显示。但是,即使我设置了关系,MS Access 仍会不断抛出有关查询与 table 之间未定义关系的错误。

失败后,我尝试使用相关查询和 table 进行 editable 查询,但我所做的查询中 none 有 editable 记录集,原因我不太明白。据我所知,查询和 table 之间的关系是一对一的,链接的 table 通常是 editable 直接在 MS Access 中。即使我放弃附加信息查询,只是将链接的 table 加入到我的错误查找直通查询中,我也无法创建 editable 记录集。

有什么好的方法可以实现我的目标吗?我开始觉得我最好的选择是在 Access 中创建某种临时 table 来存储我正在编辑的值,然后将它们合并到链接的 table 中,但这似乎对我来说有点笨拙。我还有其他选择吗?

好吧,也许你在找到那些坏行(或任何原因)之后有了存储过程,你有了它 return 那个键列表。

那么下一个问题就变成了?

好吧,如果你只 return 说 < 100 行,那么我认为只 return 一串 PK 值就可以了。

因此,存储过程可以:

Return 要使用 pk 值访问的一个字符串,比如

34,3443,3,55333

(在存储过程的最后语句中,只需对字符串执行 select,Access 就会将这一行、一列视为记录集)。

所以,你的代码应该是这样的:

Sub EditBad()

  Dim strKeys    As String            ' list of keys from stored procedure
  Dim rstKeys    As DAO.Recordset
  
  
  With CurrentDb.QueryDefs("MyStoredProc")
     .SQL = "exec sp_myproc " & "some possible parameters you send to stored procedure"
     Set rstKeys = .OpenRecordset
  End With
  
 strKeys = rstKeys(0)
 rstKeys.Close
 
 ' now launch our edit form based on the keys returned
 
 Dim strWhere    As String
 
 strWhere = "ID IN (" & strKeys & ")"
 
 DoCmd.OpenForm "frmEditBadGuys", , , strWhere
 
 
End Sub

现在,要returned 的坏键列表是否会变大?好吧,那么从存储过程中,只需将 return 的值作为 table。因此,代替存储过程中“键字符串”上的单个 select,您 return 一个 select 要检查的错误键值。

所以,现在我们有:

  With CurrentDb.QueryDefs("MyStoredProc")
     .SQL = "exec sp_myproc " & "some possible parameters you send to stored procedure"
     Set rstKeys = .OpenRecordset
  End With
 strKeys = ""
 do while rstKeys.EOF = False
    if strKeys <> "" then strKeys = strKeys & ","
    strKeys = strKyes & rstKeys(0)
    .movenext
 loop
 rstKeys.Close

 strWhere = "ID IN (" & strKeys & ")"
 
 DoCmd.OpenForm "frmEditBadGuys", , , strWhere

同样,我认为此解决方案适用于 100-200 行。

如果结果 returned 是说 1000-2000 条记录?那么 "in (value1, value2) 等字符串变得太长,运行s 太慢,并且会爆炸 - 你限制在我认为大约 4000 个字符 - 但是 [=71= 中的这样一个 where 子句] 已经太长了,它会 运行 乌龟慢。

所以,不是将 returned 记录集处理成一个长字符串吗?

将结果发送到本地临时文件 table。然后您可以创建一个 editable 表单,并在本地 table 上加入链接 table。在这种情况下,确保基础 table 是链接的 table,并且您可能必须对本地临时 table 进行左连接(内部可能有效,但左应该工作。

如果真的需要性能呢?好吧,将数据 sql 服务器端发送到临时 table(现在,临时 table,我不是指实际的 sql 服务器临时 table ,因为您不能在 Access 中使用这些客户端。(您使用什么设置将取决于此应用程序必须是多用户)。

因此,您可以创建一个 sql 服务器视图(执行此连接)。请记住,sql 服务器视图是来自客户端访问的 editable(不同于传递查询 - 它们大部分是只读的)。

因此,您还可以在“某种临时”table sql 侧有一个“用户”列,您不仅可以添加 PK 值,还可以添加用户列名称.然后在访问客户端?您启动“bad guys/bad data”编辑表单并使用基于用户名的 where 子句(这将允许多用户设置)。到目前为止,此设置的性能最好。

所以,让存储过程吐回去要么:

  • 具有键的存储过程中的一列 select,并尝试将“in 子句”作为您知道有效的客户端表单的 where 子句(可以编辑数据)。但是,我似乎记得访问客户端在 SQL 服务器的“子句”方面做得不好 - 你必须试试这个想法。

  • PK 值的本地 table 也可以很好地工作 - 代码不多,这将基于链接的 table 连接 + 左连接到您写出的本地 table 个 PK 值。如果链接的 table 不是太大,那么这可以工作(但同样会出现性能问题)。

因此,最终性能将是服务器端视图,并且它与您想要处理的不良 PK 值的临时工作 table 相结合。对于多用户,则您必须添加一个“用户”列或某种方式来允许多个用户。请记住,来自访问客户端的“where”子句对视图非常有效。 (但不是那些 where "in (1,2,3) types of where clauses!

所以,以上 3 条可能的道路可供尝试。