【问题标题】:How to access SQL Server from VBA in a non-deprecated way?如何以非弃用方式从 VBA 访问 SQL Server?
【发布时间】:2014-12-09 00:03:55
【问题描述】:

似乎所有从 VBA 项目直接访问 SQL Server 数据库的方法都已被弃用:

  • 带有 ODBCDirect 的 DAO:Access 2007 已放弃支持。
  • DAO via JET:你不是认真的,对吧?无论如何,它是 Microsoft 的 considered obsolete
  • 带有 SQLOLEDB 提供程序的 ADO:Deprecated
  • 带有 SQL Server Native OLEDB 提供程序的 ADO:Won't be supported after SQL Sever 2012
  • 带有用于 ODBC 的 Microsoft OLE DB 提供程序的 ADO:Not supported“用于 ODBC 的 Microsoft OLE DB 提供程序 (MSDASQL) 不支持 SQL Server Native Client。”

我错过了什么? Microsoft 批准的从 VBA 访问 SQL Server 数据库的官方方法是什么(毕竟,已弃用,仍然是 Office 2013 中包含的官方开发语言)?

【问题讨论】:

  • 我多年来一直在使用 ADODB 或 DAO,从未遇到任何与 deprecation 相关的错误...Driver={SQL Server}?
  • 当我不使用链接表时,我一直在使用 DAO,它运行良好。它是 Access 中的“原生方式”,我从未听说它已被弃用(预计在 2007 年会有一段时间?)。使用 DAO 时,我什至看不到它是 odbc direct 还是 jet。谁在乎呢?
  • @vba4all:我也不是,但这并不奇怪:弃用并不意味着“它不再工作”,弃用意味着“不要将它用于新开发,它可能随时停止工作”。我们目前正在重新设计 VBA 应用程序的数据访问层,所以我很好奇目前推荐的访问 SQL Server 数据的方式。
  • @iDevlop:我在乎。 :-) 如果看不到是 ODBC direct 还是 JET,那么您可能正在使用 JET,这意味着您必须使用 JET SQL 语法,并且不能使用任何本机 T-SQL 语句(公用表表达式等)。
  • @Heinzi:对,但是您可以轻松地创建直通查询,无论是纯粹在 VBA 中还是在保存的查询中。性能与其他客户端相当,在 Oracle 和 Sql Server 上使用相当大的表进行测试。在这种情况下,您使用的是服务器的语法。

标签: sql-server vba excel ms-access


【解决方案1】:

在 vba 中初始化 adodb.connection 时,我们替换了

          .Provider = "sqloledb"
          .Properties("Data Source").Value = sServer
          .Properties("Initial Catalog").Value = sDB
          .Properties("Integrated Security").Value = "SSPI"

           .ConnectionString = _
               "DRIVER={ODBC Driver 11 for SQL Server}; " & _
               "SERVER=" & sServer & "; " & _
               "Trusted_Connection=Yes; " & _
               "DATABASE=" & sDB & "; "

使用 .Provider = "MSDASQL.1" 但您不必添加它。

【讨论】:

    【解决方案2】:

    正确和未来的方法是使用 ACE 对象模型。您 100% 正确地认为本机 oleDB 正在从 SQL 服务器中删除。还需要注意的是,当 .net 出现时,“一般”开发人员社区开始放弃 ADO(ado.net 提供程序是一种非常不同的野兽,它不依赖于 oleDB,而是依赖于 sqlprovider)。

    因此,我们的行业正在出现重大趋势。

    我们远离 oleDB。这通常是一种仅限 Windows 的技术。随着 iPad、智能手机、Android 等的兴起,你没有这样的平台特定提供商,他们也没有 oleDB。因此,您必须使用开放式数据库连接标准 (ODBC) 恢复到 TOWARDS。甲骨文、微软、MySQL都表示这是未来的道路和选择。

    虽然 JET 被认为已过时,但 ACE 并非如此。

    自 Access 2007(现在是完整的 3 个版本)以来,您不应该也不应该参考 DAO。因此,对于最后 3 个版本的 Access,您不需要也不希望或使用对 DAO 对象库的引用。

    您现在应该使用新的内置 ACE 数据库引擎。这意味着您不需要单独引用 DAO。

    ACE 引擎有几个优点:

    您不再需要 DAO 引用。

    一旦对数据引擎的引用负责处理前两个库引用。

    有 x32 和 x64 位版本可用(因此 .net 应用程序等可以使用此数据引擎的 x64 位版本)。 JET 只有 x32 位。

    ACE 提供程序会继续接收更新和增强功能。 JET 和 ADO 都不能这么说。

    ACE 现在支持存储过程和表触发器。它还支持基于 Web 服务的 SharePoint 列表。

    还对 Access/ACE 进行了更改以使用 SQL Azure。

    要在 SQL Server 中使用 Access,您只需使用 ACE 和链接表。如前所述,远离 ADO MUCH 的趋势始于大约 13 年前 .net 出现时。

    因此,现在推荐的标准方法是 ACE + odbc。

    所以你在这里没有错过任何东西。令人困惑的主要原因是文章指出 JET 已被贬值,但随后遗漏了非常重要的细节,即 Access for THE LAST 3 个版本现在不使用 JET,而是使用一个名为 ACE 的新库。

    重要的是,您不再需要也不希望在您的访问应用程序中引用 DAO。

    您肯定在使用兼容的 DAO 库,它甚至仍然建议您在 reocrdset 代码前加上 DAO(因此,如果您过去这样做,或者您总是忽略 DAO,那么旧的现有代码也可以正常工作声明记录集时的限定符。

    对于像 sql pass 这样的事情,您可以简单地使用保存的 pass through 查询,然后执行以下操作:

       CurrentDb.QueryDefs("MyPass").Execute
    

    或者一些t-sql怎么样,你可以这样做:

    With CurrentDb.QueryDefs("MyPass")
      .SQL = "ALTER TABLE Contacts ADD MiddleName nvarchar(50) NULL"
      .Execute
    End If
    

    或使用参数“即时”调用您选择的存储过程

    With CurrentDb.QueryDefs("MyPass")
      .SQL = "Exec MyStoreProc " & strMyParm1
      .Execute
    End If
    

    以上这些不是很好很干净吗?如前所述,上面的代码示例往往比使用 oleDB/ADO 示例发布的代码更少且麻烦。

    对于长期使用 ODBC 和 sql server 开发技能的 Access 用户来说,您无需做任何事情,因为行业在很大程度上决定了您一直在做的事情是推荐的方法。

    虽然 ACE 不支持 JET-DIRECT,但我想不出有什么情况会因为使用上述 pass-through querydef 示例代替 JET direct 而错过此选择。

    【讨论】:

    • +1,提出了好点。不过,我暂时将这个问题留待解决,以防万一有人能提出纯 VBA 解决方案(例如,可以在 Excel 和 Access 中使用,而无需添加“中间 ACCDB”)。跨度>
    • 你有一个很好的观点,这是从 Access 中“简单”的。在 Excel 中,我仍然会考虑使用 ADO。虽然 oleDB 从 SQL 服务器的 v-next 中删除,但您仍然可以将 oleDB 与 ODBC 提供程序一起使用。所以这意味着“一般”您仍然可以编写和使用 ADO 代码,但是 ADO 将因此使用 ODBC 提供程序而不是 oleDB 提供程序在未来(因此您不必太在意)。因此,作为“仅限访问”的问题,这是一个简单的答案。您的介绍和在这种情况下使用 Excel 确实增加了您的挑战。我承认您可以继续在 Excel 中使用 ADO。
    • 但遗憾的是,新的 ACE 引擎仍然以“DAO”库的形式存在。
    【解决方案3】:

    我错过了什么?

    普通的旧 ODBC。在 Access 以外的 Office 应用程序的 VBA 项目中,通过 ADO 的 ODBC 是最直接的:

    Sub AdoOdbcExample()
        Dim con As Object
        Set con = CreateObject("ADODB.Connection")
        con.Open _
                "Driver={SQL Server Native Client 11.0};" & _
                "Server=.\SQLEXPRESS;" & _
                "Database=myDb;" & _
                "Trusted_Connection=yes;"
        con.Execute "UPDATE Clients SET FirstName='Gord' WHERE ID=5;"
        con.Close
        Set con = Nothing
    End Sub
    

    对于 Access 中的 VBA 项目,我们还可以像往常一样通过 ACE DAO 使用 ODBC 链接表和传递查询

    Sub DaoOdbcExample()
        Dim cdb As DAO.Database, qdf As DAO.QueryDef
        Set cdb = CurrentDb
        Set qdf = cdb.CreateQueryDef("")
        qdf.Connect = "ODBC;" & _
                "Driver={SQL Server Native Client 11.0};" & _
                "Server=.\SQLEXPRESS;" & _
                "Database=myDb;" & _
                "Trusted_Connection=yes;"
        qdf.sql = "UPDATE Clients SET FirstName='Gord' WHERE ID=5;"
        qdf.ReturnsRecords = False
        qdf.Execute dbFailOnError
        Set qdf = Nothing
        Set cdb = Nothing
    End Sub
    

    注意事项:

    1. SQL Server Native Client 11.0 是 SQL Server 2014 附带的版本(参考:here)。

    2. Obsolete Data Access Technologies 的引用列表显示“DAO 3.6 是该技术的最终版本。它将在 64 位 Windows 操作系统上不可用。”。这指的是 Jet DAO(“Microsoft DAO 3.6 对象库”)。如果安装了 64 位版本的 Access 数据库引擎,ACE DAO(“Microsoft Office 14.0 Access 数据库引擎对象库”)确实可用于 64 位应用程序。

    【讨论】:

    • 实际上,您的第一个选项使用 MSDASQL,OLEDB->ODBC 映射器,which is the default ADO provider used if no Provider=... clause is present in the connection string。它可能会起作用;但是,正如问题中所述,微软明确“不支持”。 +1 提到 ACE DAO!
    • @Heinzi Point 回复:MSDASQL。事实上,我刚刚检查了“Microsoft ActiveX Data Objects 2.8 Library”和“Microsoft ActiveX Data Objects 6.0 Library”都将“MSDASQL.1”报告为.ProviderConnection 对象。如果 SQL Server Native Client 破坏了 MSDASQL 并且 SQL Server 的一大堆 VBA 代码必须从 ADO 迁移到 ACE DAO,那肯定会很讽刺! (我当然希望这不会发生......)
    • 我建议将 Driver={SQL Server Native Client 11.0} 更改为 Driver={ODBC Driver 17 for SQL Server} 以使用 Microsoft ODBC Driver for SQL Server 基于 Driver history for Microsoft SQL Server 说“不建议使用 [SQL Server Native Client] 进行新开发。”和MSODBCSQL announcement
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多