【问题标题】:Cannot use pass through queries in Excel无法在 Excel 中使用传递查询
【发布时间】:2016-06-24 16:04:44
【问题描述】:

我已经搜索了好几天的多个论坛,但仍然卡住了。希望有人能在这里阐明一下。

我对 MS Office 和原生 SQL 之间的 SQL 语法差异越来越感到沮丧,并且我被引导相信使用传递查询将允许我使用原生 SQL。我尝试了来自各个论坛的多项建议来创建直通查询,但我的查询中仍然遇到 Office(语法)错误。

下面是我的代码的一个简单示例,由于 ISNULL 语法,Excel/VBA 不喜欢它。请注意,问题不是 ISNULL 本身,我知道如何解决这个问题。这只是举例。问题在于它应该在本机 SQL 中工作(并且在 SQL Server Management Studio 中也可以)。

为了完整起见,我正在使用:

  • SQL Server 2014

  • MS Excel 2013

  • Microsoft DAO 3.6 对象库

我怀疑连接字符串或 DAO 对象库可能是罪魁祸首,但我已经尝试了多个其他结果。

完整的示例(在 OpenRecordSet 上失败)代码如下。如果能提供任何帮助,我将永远感激不尽。

谢谢, 瑞恩

Option Explicit

Sub TestQuerySQL()
Dim sqlConnect As String, dsnName As String, dbName As String, sqlString As String, db As Database, qd As QueryDef, rs As Recordset

   dsnName = "MyDSN"
   dbName = "MyDatabaseName"

   sqlConnect = "ODBC;DSN=" & dsnName & ";Trusted_Connection=yes;"
   sqlString = "Select isnull(d.Name, '???') as DealerName from Dealer d"

   Set db = OpenDatabase(dbName, dbDriverNoPrompt, True, sqlConnect)

   On Error Resume Next
   Set qd = db.CreateQueryDef("", sqlString)

   If Err.Number <> 0 Then
      MsgBox "CreateQueryDef failed. SQL=>" & sqlString & "< " & Err.Number & " Err=>" & Err.Description & "<", vbCritical
   Else
      qd.ReturnsRecords = True

      Set rs = qd.OpenRecordset(dbOpenSnapshot, dbReadOnly)

      If Err.Number <> 0 Then
         MsgBox "OpenRecordset Failed. SQL=>" & sqlString & "< Err=>" & Err.Description & "<", vbCritical
      Else
         MsgBox "Success"
         'do someting with the results
      End If
   End If
End Sub

【问题讨论】:

  • 忘了提一下,如果有帮助,我收到的错误消息是“查询表达式'isnull(d.Name,'???')'中函数使用的参数数量错误”,这是 Excel/Access 对该函数使用不同语法的结果。
  • SQL 是一种没有单一实体拥有的语言,并且各种 RDMS 维护着不同的方言。因此,MS Access SQL 与 SQL Server SQL 不同,MySQL/Postgre/DB2/SQLite SQL 也不同。所以没有真正的native SQL。
  • ISNULL() 在 Access 和 MSSQL 中使用,但在不同的实现中。对于 Access,此不带参数的函数返回 true/false,但不返回 SQL Server。您是连接到 SQL Server 还是 .mdb/.accdb 数据库?如果是前者,您的查询是有效的。如果是后者,你的错误就会出现。
  • @Parfait:我正在连接到 SQL Server,所以我相信我的查询应该可以工作。简而言之,我希望根据 SQL Server 语法验证我的代码。

标签: sql-server excel vba


【解决方案1】:

在记录集行中指定dbSQLPassthrough 选项。如果没有此指定,JET/ACE DAO 引擎将使用其自己的 SQL 方言,因此将 ISNULL() 解释为逻辑函数,而不是将 SQL Server 的 ISNULL() 解释为值函数。下面不使用querydef直接打开记录集:

DAO 连接

Set db = OpenDatabase(dbName, dbDriverNoPrompt, True, sqlConnect)
Set rs = db.OpenRecordset(sqlString, dbOpenDynaset, dbSQLPassThrough)

ADO 连接

或者,使用可以读取任何外部 SQL 引擎方言的 ADO 连接:

Dim conn As New ADODB.Connection, rst As New ADODB.Recordset
Dim sqlConnect As String, sqlString As String

' REFERENCE THE MICROSOFT ACTIVEX DATA OBJECTS XX.X LIBRARAY '
sqlConnect = "ODBC;DSN=" & dsnName & ";Trusted_Connection=yes;"
sqlString = "Select isnull(d.Name, '???') as DealerName from Dealer d"

conn.Open sqlConnect
rst.Open sqlString, conn

【讨论】:

  • 冻糕,感谢您提供的两个选项。当我使用 DAO 时,我选择了第一个,它运行良好。我已经阅读了几篇论坛帖子,您需要使用 QueryDef 来处理直通查询,这显然是不正确的,但我为此苦苦思索了一周左右的主要原因。再次感谢 Parfait。
  • 很高兴为您提供帮助。我也学到了一些东西,因为我只在 MS Access 中严格使用 DAO,直到现在才在 Excel 中使用!好问题。
猜你喜欢
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多