【问题标题】:Based on Excel VBA, is it better to create ADODB objects Or to use DOCMD.RUNSQL? Which are the pro & contra? [closed]基于 Excel VBA,是创建 ADODB 对象还是使用 DOCMD.RUNSQL 更好?哪些是赞成和反对? [关闭]
【发布时间】:2016-04-28 16:54:48
【问题描述】:

根据标题,创建 ADODB 对象或访问对象然后使用 DOCMD.runsql 更好吗?我通常使用 Excel 工作表和访问表。哪种方法更快,哪种方法最灵活可靠?有一些具体的赞成或反对?

【问题讨论】:

    标签: excel vba ms-access ado adodb


    【解决方案1】:

    简短的回答是:

    1. ADODB 更快、更可靠,而且它可能具有 您需要的功能;
    2. Access Application 对象具有更丰富的功能,如果您真的 需要它;
    3. Access Application 对象可能(也可能不会!)允许您运行 带有嵌入式 VBA 的 SQL 和查询对象。

    更详细...

    如果您使用 DoCmd,则您已将 MSAccess.exe 的副本实例化为您的 Access 应用程序对象的一部分 - 这是相当多的内存,并且需要几秒钟才能启动:这不是您想要的做一个微不足道的任务。

    但是,您现在可以使用所有 Access 应用程序对象的方法和属性 - 不仅仅是 DoCmd,您还拥有所有 CurrentDB 对象,包括 querydefs 集合。因此,如果这是一项复杂的任务,而不仅仅是“运行这个微不足道的查询”,Access Application 对象具有优势。

    一个很大的缺点是您无法将此工作表分发给在其工作站上没有 MSAccess.exe 的用户:他们的 VBA 无法创建 MS-Access 应用程序及其 DoCmd 方法的实例。

    创建 ADODB 对象要快得多,而且每个拥有 MS-Office 的人都有用于 MS-Access 的 OLEDB 数据库驱动程序,即使他们的计算机上没有“专业”版 Office 或 MS-Access。

    对象实例化是这里最大的性能问题:MS-Access 的 ADODB 对象和 OLEDB 数据库驱动程序运行查询的速度也比 MS-Access.exe 稍快,但这并不是您会注意到的性能优势。

    请注意,ADODB 连接对象将为您提供详细的错误和状态信息,并且您可以设置超时(在连接上,以及命令对象或记录集对象),以保护您免受慢速查询或失败的 MS-Access进程。

    如果您是一位经验丰富的开发人员,能够很好地掌握事件驱动编程和 Access 的最新 OLEDB 驱动程序的详细属性,您可能能够让 SQL 异步运行 - 启动该命令将控制权交还给 Excel,让用户继续工作,直到 ADO 对象引发“完成”事件。因此,如果您不需要数据,您可以将 SQL 作为即发即弃的操作运行,并且您可以在流程完成时使用事件过程在代码中启动响应 - 或向用户报告错误。

    但是,如果这是关于将数据返回到 Excel 表格或图表对象,则内置查询工具现在 (Office 2013) 比您在 VBA 中可以执行的任何操作(无论是 DoCmd 还是 ADODB)都更快:即使使用异步 ADO ,第一个数据块始终是同步的,并且您的 Excel 会话被“异步”VBA 命令锁定,直到它到达。

    您的 ADODB 对象肯定无法使用嵌入式 VBA 命令运行 SQL(无论是本机 VBA 还是在 MS-Access 数据库中编写的自定义代码),这会让您大吃一惊:NZ() 函数非常常见在 Access 中编写的 Jet SQL 中,如果您的 SQL 在 MS-Access 环境之外调用,它将不会运行。其他 VBA 包含不太明显,字符串处理是一个特殊的混淆来源:this Stack Overflow answer gives a detailed explanation。但是,我不确定您是否可以使用 MS-Access 应用程序对象中的嵌入式 VBA 运行 Jet_SQL 查询,如果它在另一个启用 VBA 的应用程序中实例化:我从未尝试过,很可能是您只能使用 MS-Access 的实际用户会话运行受 VBA 限制的 Jet-SQL。 您需要对其进行测试!

    一个快速的性能提示:您的 SQL 实际上是 MS-Access 数据库中已保存查询(DAO Querydef 对象)的名称吗?如果是这样,请考虑将其作为 ADODB.Command 对象运行,而不是将其作为 SQL 文本执行;或使用“adCmdStoredProc”选项打开记录集(并运行“执行”方法):

    rst.Open SQL, , , , adCmdStoredProc

    此外,如果初学者到中级开发人员正在阅读本文以寻找相关问题的答案,请检查您的 SQL 是否查询外部定义的链接表或 MS-Access 中的“直通”查询数据库:直接连接到任何实际托管数据的 ADODB 对象将运行得更快。

    目前我能想到的就这些了,我希望其他 Stackers 继续添加到这个答案中,以便我们得到一个完整的列表。

    【讨论】:

    • ADO 支持 Access DAO 不支持的 SQL 元素。例如,您不能在alter table 命令中使用on delete cascade on update cascade。 DAO 不支持非 jet 链接表(MS SQL、Oracle)的某些功能
    • 没错,Sergey,但您的评论需要稍微扩展:ADODB 连接支持数据库驱动程序对其可见的任何 SQL 元素 - 任何 SQL 的子集数据库引擎支持元素。因此,当您连接到 SQL Server 或 Oracle DB 时,您的示例是正确的,但不是使用 OLEDB 4.0 Jet 驱动程序的 MS-Access。 ADO 本身不“支持”元素,它的存在是为了实现数据引擎支持的任何内容。令人讨厌的是,您无法从 Supports 方法中获得所有这些信息:您必须枚举 Properties 集合。
    • 我真的很惊讶,但我的例子是 Jet。我研究了通过脚本更改 Access 数据库模式的过程,我只能通过 OLEDB 12 通过 ADO 启用级联选项,尽管数据库支持,但 Access SQL 在语法上根本没有这样的选项。
    • @Segey Jet-SQL 中的不一致非常烦人:但您的信息对我来说是新闻!我永远不会尝试这样做,每个人都“知道”它不可能工作。您的发现意味着 Microsoft OLEDB 驱动程序开发人员在遇到 SQL 中的数据描述语言关键字时,在驱动程序中实现了一个解析层,以便为系统表生成子查询(或在数据库引擎中调用未记录的函数)。或者,Jet-SQL 和 MS-Access 一直都有 DDL 命令,但它们在 OLEDB12 驱动程序中没有记录、不直观、不标准和翻译
    猜你喜欢
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 2016-12-20
    • 2021-06-09
    • 2010-10-12
    • 2011-03-05
    相关资源
    最近更新 更多