在 Access 中使用 ODBC 连接到 MS SQL Server 2012:手动调用查询和在 VBA 中调用查询之间的巨大时间差异

Posted

技术标签:

【中文标题】在 Access 中使用 ODBC 连接到 MS SQL Server 2012:手动调用查询和在 VBA 中调用查询之间的巨大时间差异【英文标题】:Using ODBC in Access to connect to MS SQL Server 2012: huge time difference between calling query manually and in VBA 【发布时间】:2016-07-18 14:56:37 【问题描述】:

我在使用 DAO.QueryDef 从 MS Access 2010 中的 MS SQL Server 2012 检索数据时遇到问题。设置是 MS SQL Server 2012 作为后端,在 MS Access 2010 中使用链接表、视图、传递查询、存储过程和函数实现了 GUI。两者之间的连接是通过 ODBC 驱动程序“SQL Server”建立的。

当我手动执行查询时,即在 MS Access 的“查询”部分中双击它,然后我被要求输入两个输入参数,qry 需要几秒钟才能返回数据(进入本地访问 GUI 中的临时表)。

但是,当我尝试在 VBA 代码中调用某些查询时,它需要大约 10 倍于手动执行的时间,或者我什至会超时(运行时错误 3164:ODBC 调用失败)。

有问题的代码归结为:

Private Sub cBCreate_Click()
    Dim thisDb As DAO.Database
    Dim qdf As DAO.QueryDef

    [...] //File Dialog

    Set thisDb = CurrentDb
    Set qdf = thisDb.QueryDefs("qry_10")
    qdf.Parameters!parAbrg = aInputValue //from unbound combo box
    qdf.Parameters!parDate = bInputValue //from unbound combo box
    qdf.Execute

    [...] //sth else

    qdf.Close
    Set qdf = Nothing
    Set thisDb = Nothing
End Sub

有没有人遇到过这种情况并且可能有解决方案?非常感谢任何帮助或想法。

-斯蒂芬

更新

parAparB 都是来自两个未绑定组合框的输入值,该组合框位于未绑定表单上,单击了按钮 cBCreate。 parA 是一个由 2..4 个数字字符组成的字符串(例如“2180”),parB 是一个类似于德国日期的字符串(例如“01.04.2016”)。当我如上所述手动触发 qry 时,我以这种格式输入它们。

qry 触发器没什么特别的。它从一个视图中检索数据 LEFT JOINing 它与两个 ID 上的一个表。输入参数在 WHERE 子句中使用。这是代码:

SELECT
    36 fields
INTO
    tblExportTmp
FROM
    vw_09 wvn
LEFT JOIN
    tblAbger AS awg
ON
    (wvn.wOutId = awg.wOutId) AND
    (wvn.wInId = awg.wInId)
WHERE
    wgAbrg = [parAbrg] AND

    (
        (wOutTime Is Not Null AND
        CVDate(wOutTime) < DateAdd('m', 1, [parDate])) OR

        (awg.wInId Is Null AND
        awg.wOutId Is Null AND
        DateDiff('m', CVDate(wOutTime), [parDate]) > 0) Or

        (outTime Is Null AND
        DateDiff('m', CVDate(wInTime), [parDate]) >= 0)
    )

    AND
    (
        awg.wInId Is Null AND
        awg.wOutId Is Null
    )

ORDER BY
    5 fields ASC;

文件对话框用于指定检索到的数据最终应保存到的 XLSX 文件。

更新 2

是的,在单击触发 VBA 代码的按钮 cBCreate 之前,我确实从所述组合框中选择了 aInputValuebInputValue。视图和表都从同一个 SQL Server 链接。 wInTimewOutTime 是原始表和视图中的时间戳,但由于美国和德国时间戳之间的混淆,它们作为文本字段链接。

我添加了错误处理,它说查询显然超时。我将超时设置为 600,这样它至少会给出结果,但是与手动执行查询相比,它花费的时间太长了。

【问题讨论】:

请发布实际的 SQL 查询。 inputValues 是从哪里得出的?文件对话框中的内容? 更新了 SQL 查询,有关输入变量的信息。 我无法重现您的问题。如果aInputValuebInputValue 是组合框值,您是否在运行VBA 代码之前选择组合框项?两个表是否都链接了 SQL Server 表?是 wOutTimewInTime 日期字段(检查表格的设计视图,即使您无法编辑任何内容)?还要添加dbengine error handle,因为 ODBC Called Failed 是一个包罗万象的通用消息,而不是具体描述。 您能否查看 vba 查询和直接查询的 SQL 分析器,以确保在 vba 中正确生成 sql,尤其是 where 条件及其数据类型。尝试将数据库表/查询拆分为来自 GUI 的单独 ms 访问。 中间的[arDate]也应该是[parDate]吧? -- 您可以尝试在查询中使用参数部分或查询设计器的参数对话框显式声明参数及其数据类型(字符串和日期)吗? 【参考方案1】:

在查询中添加一个 PARAMETERS 部分,并使用它们的数据类型(字符串和日期)显式声明参数会有所帮助。

(实际上对我来说有点惊讶。)

组合框的值也必须转换为适当的数据类型。

【讨论】:

以上是关于在 Access 中使用 ODBC 连接到 MS SQL Server 2012:手动调用查询和在 VBA 中调用查询之间的巨大时间差异的主要内容,如果未能解决你的问题,请参考以下文章

使用 MS Access 和 ODBC 连接到远程 PostgreSQL

除了 ms-access 之外,我可以使用哪些其他程序连接到 odbc 数据库

MS-Access ODBC 连接到 Oracle for SQL

在 Access 中使用 ODBC 连接到 MS SQL Server 2012:手动调用查询和在 VBA 中调用查询之间的巨大时间差异

通过 ODBC 连接到 SQL Server 的 Access 中的 MS SQL 查询

如何让 ms-access 以其他用户身份连接到 ms-sql?