jac*_*ouh 6 sql-server ms-access ms-access-2007 passthru pass-through
在带有SQL Server后端的Microsoft Access 2007中,我们通常将SQL Server中的链接表作为可编辑表单的Form.RecordSource用于单个表数据修改.本地查询用于组合来自多个链接表的字段的交叉表版本.本地查询本身必须是可更新的,以便修改编辑表单上的数据.
现在我们计划通过Passthrough查询替换所有本地查询,以便直接使用本机SQL Server表.
我尝试使用以下SQL字符串创建一个名为qrySelProductsPassThroughEditable的非常简单的passthru查询:
SELECT dbo.Products.ID, dbo.Products.Name FROM dbo.Products;
Run Code Online (Sandbox Code Playgroud)
ID字段是在SQL Server中定义为主键的IDENTITY字段作为定义:
CREATE TABLE [dbo].[Products](
[ID] [int] IDENTITY(1,1) NOT NULL,
....
)
Run Code Online (Sandbox Code Playgroud)
但Access传递查询返回的数据表根本不可编辑.所以它不能用作.RecordSource来编辑表单.
这与链接相反,该链接表示如果passthru查询包含所有相关表的所有主键,则查询将是可编辑的.
通过下面的讨论,Microsoft Access 2007 .accdb,.accde或.accdr(Access运行时)中的直通查询始终是只读的,它永远不可编辑.您应该将它用作最终列表,或者作为报表的.RecordSource,而不是用于必须使用链接表的表单,或者是涉及数据IO的链接表的可写普通查询.
根据我上面的评论和Yawar的回答,我不知道Pass Through Queries是可编辑/可更新的.它们是可编辑的,因为您可以编辑保存Pass Through Query对象,但我不相信Pass Through Query可以生成可编辑的记录集.
基本上有两种方法可以将Access连接到非Access数据源.
第一种方法,也是最流行的方法,是使用某种形式的链表,通常是ODBC链表.有多种方法可以将ODBC链接表与MS Access一起使用,但大多数开发人员更喜欢使用在应用程序启动时刷新或重建(删除并重新连接)的DSN-Less连接.请注意,使用ODBC时,您仍然使用DAO.DAO是MS Access中内置的默认数据访问对象,即使您没有专门编写任何DAO代码,MS Access仍然使用DAO将表单,报表和查询链接到您的数据源.在ODBC的情况下,实际上最终有两个数据访问层在工作,DAO和ODBC.但是你可以使用ODBC/DAO具有相当不错的性能而无需编写代码(除了维护ODBC链接表).
第二种方法是使用ADO.与流行的看法相反,这并不意味着您必须使用未绑定的表格.但它确实意味着您必须编写比使用JET/DAO/MSAccess或DAO/ODBC/SSQL Server更多的代码.您必须编写代码以将数据库中的记录引入ADO Recordset,然后使用代码将表单绑定到该Recordset.您必须编写更多代码以使子表单与父表单保持同步,在创建新记录时将外键插入子表单,以及用于过滤和排序等各种其他内容,如表单的内置过滤和排序选项通常不适用于ADO记录集.ADO是与SQL Server交流的好方法,因为它真的给你很多控制权,但是因为它的代码很强,而且因为ODBC链接表工作得很好,大多数开发人员不建议使用ADO,除非没有其他方法可以做你想做的事情.这方面的一个例子是调用存储过程.我相信Pass Through Queries可用于调用存储过程,但我也认为存在一些限制(例如使用参数).我相信在大多数情况下,开发人员使用ADO来调用存储过程.我用ADO了很多,但我不太使用存储过程(目前还没有),所以我没有很多这方面的资料.
值得一提的另一件事是带有ODBC的DAO使用"延迟加载",但是ADO会强制您提取所有数据,这些数据可能非常耗时并且如果您拥有数百万行,则会占用大量内存.否则你需要实现某种分页.
我自己创建单个DSN-Less ODBC Linked表的功能如下所示.如果您是Access和VBA的新用户,这可能对您没有多大意义.代码删除了您尝试链接的表已存在的任何表定义,这有点危险,因为我相信它可以删除您不想要的本地非链接表.这里的错误处理也没有真正达到速度,但是由于涉及的复杂性,大多数在线示例代码在其中没有良好的错误处理.在链接表上创建主键索引并不总是必要的.我只是将它内置到我的函数中,因为我需要一次特定项目,所以现在我把它留在那里并使用它,无论好坏.
要正确使用此代码,您确实需要在某处列出所有链接表,并遍历该列表并为每个表调用此函数.此功能允许您使用与SQL Server中的实际名称不同的名称链接表.您还需要一种构建有效ODBC连接字符串的方法,该字符串也必须传递给此函数.
Private Sub LinkODBCTable(sSourceTableName As String, _
sLocalTableName As String, _
sPrimaryKeyField As String, _
sConString As String)
Dim dbCurrent As DAO.Database
Dim tdfCurrent As DAO.TableDef
Set dbCurrent = DBEngine.Workspaces(0).Databases(0)
On Error Resume Next
'Be Careful, this could delete a local, non-linked table.
dbCurrent.TableDefs.Delete sLocalTableName
If Err.Number <> 0 Then
If Err.Number = 3011 Then
'Table does not exist
Else
MsgBox "Error in LinkODBCTable" & vbCrLf & vbCrLf & Err.Number & " " & Err.Description
End If
Err.Clear
End If
On Error GoTo 0
Set tdfCurrent = dbCurrent.CreateTableDef(sLocalTableName)
tdfCurrent.Connect = sConString
tdfCurrent.sourceTableName = sSourceTableName
dbCurrent.TableDefs.Append tdfCurrent
On Error Resume Next
If sPrimaryKeyField <> "" Then
dbCurrent.Execute "CREATE INDEX __UniqueIndex ON [" & sLocalTableName & "] (" & sPrimaryKeyField & ")", dbFailOnError
If Err.Number <> 0 Then
If Err.Number = 3283 Then
'Primary Key Already Exists
Else
MsgBox "Error in LinkODBCTable" & vbCrLf & vbCrLf & Err.Number & " " & Err.Description
End If
Err.Clear
End If
End If
Set tdfCurrent = Nothing
Set dbCurrent = Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)
有关DAO,ADO,Pass Through Queries,SQL Server等应该检查的一些非常好的资源:
http://technet.microsoft.com/en-us/library/bb188204%28v=sql.90%29.aspx
http://www.utteraccess.com/wiki/Choosing_between_DAO_and_ADO
这是将表单绑定到ADO Recordset的示例.这有点误导,因为最好让一个全局连接对象在应用程序运行时保持打开状态.这允许您使用可自动更新的ADO记录集.使用此练习还可能使您的记录集成为表单级对象.
http://msdn.microsoft.com/en-us/library/office/bb243828%28v=office.12%29.aspx
在 MsAccess 查询窗口中打开任何 SQL Server Select 语句(一个表、一个视图或一个带有许多连接表的 sql-select)并且是可编辑/可更新的:
打开 Access 查询窗口并输入您的 SQL 语句。将表名替换为方括号内 SQL Server 的完整 ODBC 字符串,后跟一个点以及架构和表名,如下例所示:
前:
SELECT SOH.SalesOrderID, SOH.OrderDate
FROM Sales.SalesOrderHeader as SOH
Run Code Online (Sandbox Code Playgroud)
后:
SELECT SOH.SalesOrderID, SOH.OrderDate
FROM [ODBC;Driver=SQL Server;Server=myServer;Database=AdventureWorks2012;Trusted_Connection=Yes;MarsConn=yes;].Sales.SalesOrderHeader as SOH
Run Code Online (Sandbox Code Playgroud)
评论:
| 归档时间: |
|
| 查看次数: |
16098 次 |
| 最近记录: |