我正在开发一个连接到2008 SQL Server后端的Microsoft Access中非常复杂的旧式ADP项目。常见的使用场景是数据表视图中的表单,其中包含可编辑的记录集。
大多数数据库使用的方法是加载表单,然后使用表单参数在VBA中动态构建SQL,并将SQL应用为表单的RecordSource
。许多查询都非常复杂,因此这会造成非常难看的代码和维护噩梦。
对于只读记录集,我已将动态sql转换为参数化存储过程,这非常有用。很好,干净,易于维护。
但对于可编辑的记录集,我试图确定最佳方法:
1。动态SQL - 如上所述,我真的想避免这种方法。
2。 SQL视图 - 这里的挑战是一些表非常大,所以如果我尝试加载视图然后在表单上过滤它,它必须从SQL服务器中提取整个记录集,即使我只需要少量的行。 (负面性能和IO影响。)
第3。使用context_info
- 这听起来很有趣,但听起来不像基于此处讨论的推荐方法:Create parameterized VIEW in SQL Server 2008如果我针对SQL Server 2016进行开发,我可能会更多地考虑{{3} }。
4。带视图的参数表 - 这是我倾向于的一个想法。我将在SQL中创建一个Parameters
表,并使用会话ID设置参数值(作为键/值对)。然后,视图将根据参数表中的当前值进行过滤。这将允许我使用视图作为我的RecordSource
来支持编辑,但过滤将在SQL Server端进行。
参数表确实是这个项目的最佳方法,还是有另一种方法可以访问在服务器端过滤的参数化读写记录集?
答案 0 :(得分:1)
我假设您现在正在讨论非adp项目。
即使您不使用视图,并且说直接将表单绑定到100万行的链接表,访问权限也只会下拉您请求的记录。您只需使用打开的Form命令的表单“where”子句。
所以你甚至不必在这里使用动态SQL。
但是,您不希望启动绑定到大表的表单,除非您设置了where子句。
您当然可以在没有reordsource的情况下打开表单,让用户在文本框中输入一些参数值,然后转到:
Dim strSQL as string
strSQL = "select * from tblCustomers where InvoiceNum = " & me.MyInvoiceTextBox
Me.RecordSoruce = strSQL
但是,在大多数情况下,您最好创建某种类型的搜索表单。让用户输入一些值,显示如下结果:
所以在上面,这个人输入“smi”。您显示结果 (在上面我确实使用了上面的方法将sql直接填充到表单reocrdsource
中现在在侧面的编辑按钮上启动+编辑一条记录, 我只是去:
Docmd.OpenForm "frmCustomer",,,id = & me!id
再一次,即使表单直接绑定到链接的SQL服务器表,也只会从SQL服务器中提取ONE记录。所以不需要搞乱sql,也不需要搞乱参数等。
因此,具有链接表的常规非ADP访问应用程序不会拉动整个表。
您也可以在打开表单后设置表单过滤器 - 再次访问只会从链接的sql表中提取有问题的reocrds。这是一个“常见”的神话,访问拉动所有记录 - 如果你提供过滤器,它不会,我建议你打开一个表单到一个记录,让用户工作,然后关闭表单,并返回到一些搜索屏幕,其中你已准备好与下一位客户进行战斗等。
所以提供一个搜索表单 - 不建议让编辑数据的表单混乱,并且能够搜索记录。让用户编辑,然后关闭表单 - 这也促进了用户完成工作后保存的记录。
编辑: 对于具有任何类型的复杂连接等的表单,然后创建一个视图,并将表单绑定到该视图。您使用表单“where”子句,然后再次访问将只下拉一条记录。因此,对于复杂的连接等,是访问通常会使查询混乱并且运行缓慢。因此,如果表单绑定到一个表(即大多数情况),则将表单直接绑定到链接表。如果sql很复杂,那么将表单绑定到链接视图,并且如前所述,ALWAYS为openform命令提供“where子句” - 在这些情况下,它只会将一条记录拉入表单中。再一次,没有杂乱的参数,访问方面不需要杂乱的SQL - 如果你采用这种方法,你将节省大量的编码,并且你也可以获得出色的性能,因为你限制从sql server拉入该形式的reocrds。