【问题标题】:Execute a dynamic SQL Query against MS Access 2003针对 MS Access 2003 执行动态 SQL 查询
【发布时间】:2010-09-13 03:10:10
【问题描述】:

这是一个超级基本的问题,但我正在尝试执行一个查询,该查询是通过一些表单值针对表单所在的 MS Access 数据库构建的。我不认为我需要正式通过 ADO,但也许我会。

无论如何,我们将不胜感激。对不起,我是一个 n00b。 ;)

【问题讨论】:

  • 能否指定是修改数据库中的数据还是读取出来显示?在我投票支持其中一个答案之前,我需要知道 :)

标签: vba ms-access


【解决方案1】:

您可以使用以下 DAO 代码查询 Access DB:

Dim rs As DAO.Recordset
Dim db As Database

Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT * FROM Attendance WHERE ClassID = " & ClassID)

do while not rs.EOF
  'do stuff
  rs.movenext
loop

rs.Close
Set rs = Nothing

在我的例子中,ClassID 是表单上的一个文本框。

【讨论】:

  • 我会接受这个答案,除了 If 块不能作为例外(我不认为)。应该是If Not rs.EOF Then?
  • 我已对其进行了编辑以包含“not rs.EOF”和 rs.movenext。
【解决方案2】:

这就是我最终想出的真正有效的方法。

Dim rs As DAO.Recordset
Dim db As Database

Set db = CurrentDB
Set rs = db.OpenRecordset(SQL Statement)

While Not rs.EOF
    'do stuff
Wend

rs.Close

【讨论】:

  • 如果要遍历记录集中的记录,则需要rs.Movenext语句,假设SQL会返回多行。
  • 保存一组并使用 CurrentDb.OpenRecordset()。无需制作单独的数据库对象。
  • 我认为示例代码应该使用最佳实践,并且 DAO 中的 CurrentDB.OpenRecordset() 可能会使显式对象引用挂起。其次,作为示例代码,您可以在此处打开与当前数据库不同的数据库,因此作为示例代码,我认为它更好。
【解决方案3】:

这里以防万一您想要 ADO 版本:

Dim cn as new ADODB.Connection, rs as new ADODB.RecordSet
Dim sql as String

set cn = CurrentProject.Connection
sql = "my dynamic sql string"

rs.Open sql, cn ', Other options for the type of recordset to open, adoOpenStatic, etc.

While Not rs.EOF
  'do things with recordset
  rs.MoveNext   ' Can't tell you how many times I have forgotten the MoveNext. silly.
Wend
rs.Close
cn.Close
Set rs = Nothing
Set cn = Nothing

DAO 和 ADO 在用法上非常接近。您可以使用 DAO 获得更多控制权,使用 ADO 获得更好的性能。在我遇到的大多数访问数据库应用程序中,它确实没有什么区别。当我看到链接表有很大的不同时。 ADO 通常表现更好。

【讨论】:

  • 我发现 DAO 在 Access 97 格式数据库中的工作速度更快,而 ADO 在 Access 2000 及更高版本中的工作速度更快。我认为这是 jet 3.5 和 jet 4.0 之间的区别
【解决方案4】:

您得到的答案以及您似乎正在接受循环通过 DAO 记录集。这通常是完成文本的一种非常低效的方法。例如,这个:

  Set db = CurrentDB()
  Set rs = db.OpenRecordset("[sql]")
  If rs.RecordCount > 0
     rs.MoveFirst
     Do While Not rs.EOF
       rs.Edit
       rs!Field = "New Data"
       rs.Update
       rs.MoveNext
     Loop 
  End If
  rs.Close
  Set rs = Nothing
  Set db = Nothing

效率会低于:

  UPDATE MyTable SET Field = "New Data"

可以运行:

  CurrentDb.Execute "UPDATE MyTable SET Field = 'New Data'"

需要循环遍历记录集的情况很少见,并且在大多数情况下,SQL 更新速度会快几个数量级(并且会导致对数据持有更短的读/写锁)页)。

【讨论】:

  • 嗯,问题实际上并没有说明正在执行更新。可能正在读取数据以供显示?
  • 显示在什么地方?表单?如果是这样,那么这不是最好的方法。如果在报告中,这真的不是最好的方法。对我来说,“执行查询”意味着“通过查询更新数据”,但也许我读错了 OP。
  • 实际上,他们说的是“执行查询”:大 Q = 大不同。一个查询(小 q)是一个 SQL DML SELECT,它会预先暗示一个记录集。查询(大 Q)是一个 MS Access(不是 Jet,不是 ACE)对象,它可能包含任何 SQL 语句:SELECT/INSERT/UPDATE/DELETE SQL DML,甚至是 SQL DDL 或 SQL DCL。
猜你喜欢
  • 1970-01-01
  • 2010-12-01
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多