问题 如何以非弃用的方式从VBA访问SQL Server?


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

  • 带有ODBCDirect的DAO:Access 2007已经删除了支持。
  • 通过JET DAO:你不认真,对吧?无论如何,它是 被认为是过时的 由微软。
  • ADO与SQLOLEDB提供程序: 弃用
  • ADO与SQL Server Native OLEDB提供程序: SQL Sever 2012之后将不再受支持
  • ADO与ODBC的Microsoft OLE DB提供程序: 不支持“用于ODBC的Microsoft OLE DB提供程序(MSDASQL)不支持SQL Server Native Client。”

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


11314
2017-10-14 09:02


起源

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


答案:


我错过了什么?

普通的旧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项目,我们还可以选择使用ODBC链接表和通过ACE DAO传递查询,就像我们一直有

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附带的版本(参考: 这里)。

  2. 引用的列表 过时的数据访问技术 “DAO 3.6是这项技术的最终版本。它不会在64位Windows操作系统上提供。”那指的是 喷射 DAO(“Microsoft DAO 3.6对象库”)。 高手 如果安装了64位版本的Access数据库引擎,则DAO(“Microsoft Office 14.0 Access数据库引擎对象库”)确实可用于64位应用程序。


9
2017-10-14 10:18



实际上,您的第一个选项使用MSDASQL,OLEDB-> ODBC映射器, 如果没有,则使用默认的ADO提供程序 Provider=... 子句出现在连接字符串中。它可能有用;但是,正如问题中所述,微软明确表示“不支持”。但是提及ACE DAO的+1! - Heinzi
@Heinzi Point重新:MSDASQL。事实上,我只是检查了“Microsoft ActiveX Data Objects 2.8 Library”和“Microsoft ActiveX Data Objects 6.0 Library”报告'MSDASQL.1`作为他们的 .Provider 为一个 Connection 目的。如果SQL Server Native Client破解了MSDASQL并且SQL Server的一大堆VBA代码必须从ADO迁移到ACE DAO,那肯定会很讽刺! (我当然希望不会发生......) - Gord Thompson


正确和未来的方法是使用ACE对象模型。您是100%正确的,从SQL服务器中删除本机oleDB。另外非常重要的是要注意,当.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。

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

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

所以你不要错过任何东西。令人困惑的原因很大程度上来自于JET被折旧的文章,但是其中遗漏了非常重要的细节,即最后3版本的Access现在不使用JET,但使用了一个名为ACE的新库。

显而易见的是,您不再需要也不想在访问应用程序中引用DAO。

您肯定使用兼容的DAO库,它甚至建议您使用DAO为reocrdset代码添加前缀(因此,如果您在过去执行此操作时旧的现有代码将正常工作,或者您在声明时始终忽略DAO限定符记录集。

对于像sql pass这样的东西,你可以使用保存的pass pass查询,并执行以下操作:

   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示例更少代码和麻烦。

长期以来,Access的用户围绕ODBC和sql server开发了他们的技能,你不需要做任何事情,因为行业很多决定你一直在做什么是推荐的方法。

虽然ACE不支持JET-DIRECT,但是如果使用上面的pass-though querydef示例代替JET direct,我想不出任何情况。


2
2017-10-14 21:41



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


在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”,但您不必添加它。


0
2017-10-13 14:47