对于饱受诟病的Access各个版本中存在的当字段数目过多时(不同的版本数目数目不定,有的为40个有的为50或更多),似乎Access2007依然存在此问题,当进行Update等操作时会产生“查询过于复杂”的错误。
解决的办法为下列之一:
一、重构数据库,或直接干脆换数据库产品,如SQL SERVER EXPRESS、SQLite、FB等等。
二、优化代码,这个基本上是废话。
三、如果以上两项都不行的话,那么还有个笨办法:在程序中建立一个数据库的镜像结构体、将现有数据和待更新数据存入镜像结构体,
然后删除现有数据记录,新增一条记录,并将镜像结构体中数据一次性存入数据库。
为了大家和我的方便,干脆直接摘录如下:
HOWTO: 更新 Access (Jet) 数据库中的多个 40 字段
在 Access (Jet) 数据库中更新数据使用 RDO 或 ADO 时发生以下错误:
查询是太复杂
由于要的 Jet 数据库引擎的限制如果要更新记录集包含 40 个以上的字段,也会出现此错误。
在使用 Jet 3.51 引擎更新记录集包含 50 个以上的字段如果出现错误。使用 Jet 4.0
的引擎和更高版本中,如果,则会出现此错误更新记录集包含多于 99 个,则会发生的字段。
使用 Jet 4.0 引擎和更高版本中,您可能还会看到该错误:
表达式太复杂
-或者-
定义的字段太多
本文介绍了该问题的方案、 Jet 的限制和几个解决方法。
时执行的
RDO 的 rdoResultset 对象,Update() 或 BatchUpdate() 方法或 Update() 或
UpdateBatch()...
时执行的 RDO 的 rdoResultset 对象,Update() 或 BatchUpdate() 方法或
Update() 或 UpdateBatch() 方法的 ADO 的 Recordset 对象,ODBC 错误
S1000"查询是过于复杂 (Visual Basic 运行时错误 40002) 发生。使用 Microsoft Jet OLE DB
提供程序版本 3.51 及更高版本就会具有相同说明出错。
发生此现象的原因的 ADO 和 RDO 默认行为是用来决定要在服务器上更新记录的记录集中的每个字段。也就是尝试更新时, SQL
更新查询被发送到服务器。此查询的一部分是一个 WHERE 子句,用于标识要更新记录。AND 子句出现在 WHERE
子句,为要在该标识使用每个字段中。使用 40 多个字段中更新记录集包括与 40 多个 and WHERE 子句。
Jet 引擎允许 SQL WHERE 或 HAVING 子句中的仅 40 AND 子句。jet 3.51 增加此限制为 50 的
AND 子句,并且 Jet 4.0 增加到 99 的 AND 子句限制。遇到此类的 SQL 语句时,Access
引擎会返回一个"查询是过于复杂的错误。请参阅本文的详细信息的参考部分。
有几种方法可以避免此行为:
对于新的应用程序可使用 Access 数据库时使用 DAO。DAO 专为达到此目的,并不会发出 SQL 查询来执行更新。请注意
RDO 和 ADO 尤其是旨在高效地使用许多其他类型的数据库进行操作,建议使用的与各种服务器的交互或的将是升迁以后使用
Microsoft SQL Server,例如的应用程序。
在打开记录集 (如 RDO OpenResultset 或 ADO OpenRecordset 方法中) 更新时选择特定,和
40 或更少的字段。
使用服务器端游标:
将为此请在 ADO 中 CursorLocation 位置属性设置的 Recordset 对象为 adUseServer
打开记录集之前:
...
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseServer
rs.Open ...
...
在 RDO,在调用 OpenConnection() 方法之前设置 CursorDriver rdoEnvironment
对象的属性:
...
Dim eng As RDO.rdoEngine
Dim cn As RDO.rdoConnection
Dim env As RDO.rdoEnvironment
Dim rs As RDO.rdoResultset
Set eng = New rdoEngine
Set env = eng.rdoCreateEnvironment(...)
env.CursorDriver = rdUseServer
Set cn = env.OpenConnection(...)
Set rs = cn.OpenResultset(...)
...
确保一个独一无二的密钥用于标识要进行更新而不是默认行为,使用每个字段的记录。唯一键 (尽管不一定是主关键字)
必须在这种技术来处理的是基础记录集定义。
若要执行此操作在 ADO 中 (这在 ADO 以前的版本中可能不工作 2.0),将记录集对象的"更新标准"属性设置为
adCriteriaKey。此操作有效同时用于 Update() 和 UpdateBatch() 方法:
...
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Properties("Update Criteria").Value = adCriteriaKey
rs.Open ...
...
对于 RDO,使用 ClientBatch 游标库,并确保结果集中对象的 UpdateCriteria 属性未设置为
rdCriteriaAllCols 中。默认状态下,该属性设置为
rdCriteriaKey,这将导致以确定要在服务器上更新行的主键的使用:
...
Dim eng As RDO.rdoEngine
Dim cn As RDO.rdoConnection
Dim env As RDO.rdoEnvironment
Dim rs As RDO.rdoResultset
Set eng = New rdoEngine
Set env = eng.rdoCreateEnvironment(...)
env.CursorDriver = rdUseClientBatch
Set cn = env.OpenConnection(...)
Set rs = cn.OpenResultset(...)
rs.Edit
...
rs.UpdateCriteria = rdCriteriaKey
rs.Update
...