为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?

Posted

技术标签:

【中文标题】为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?【英文标题】:Why do I get an ODBC connection failed error when using UNION ALL in Access?为什么在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误? 【发布时间】:2016-06-07 15:16:18 【问题描述】:

我正在 Access 2010 中编写一个 SQL 查询,其中的表通过 ODBC 链接到 Pervasive 客户端。当我打开表时,ODBC 连接工作正常并显示表中的值。该查询是使用 UNION ALL 将它们合并在一起的一系列查询。最近我添加了另一个 UNION ALL 查询并收到此错误:

如果我分别运行查询的每个部分,它运行良好。我通过 UNION ALL 连接的查询具有完全相同数量的字段。事实上,新查询几乎是相同的,除了其中的一部分是 where 子句。有人可以解释为什么这不起作用吗?

这是不起作用的查询:

SELECT SUM(PR_INP.Futa_5) + SUM(PR_SUTA.Amt_10) AS AMT, '67360' AS DEPT, CDATE(PaidOn) AS PayDate, 'ER Tax Exp:  FUTA/SUTA - Dept 10, 11, 12' AS Memo FROM PR_INP INNER JOIN PR_SUTA ON PR_SUTA.Loc_No = PR_INP.Loc_No AND PR_SUTA.Div_No = PR_INP.Div_No AND PR_SUTA.Emp_No = PR_INP.Emp_No AND PR_SUTA.Pay_Date = PR_INP.Pay_Date WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND PR_INP.Pay_Date = CDATE(PaidOn) AND Def_Dept IN ('010', '011', '012')
UNION ALL
SELECT SUM(PR_INP.Futa_5) + SUM(PR_SUTA.Amt_10) AS AMT, '66360' AS DEPT, CDATE(PaidOn) AS PayDate, 'ER Tax Exp:  FUTA/SUTA - Dept 13' AS Memo FROM PR_INP INNER JOIN PR_SUTA ON PR_SUTA.Loc_No = PR_INP.Loc_No AND PR_SUTA.Div_No = PR_INP.Div_No AND PR_SUTA.Emp_No = PR_INP.Emp_No AND PR_SUTA.Pay_Date = PR_INP.Pay_Date WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND PR_INP.Pay_Date = CDATE(PaidOn) AND Def_Dept IN ('013')

如果我单独运行它们,没有错误:

SELECT SUM(PR_INP.Futa_5) + SUM(PR_SUTA.Amt_10) AS AMT, '67360' AS DEPT, CDATE(PaidOn) AS PayDate, 'ER Tax Exp:  FUTA/SUTA - Dept 10, 11, 12' AS Memo     FROM PR_INP INNER JOIN PR_SUTA ON PR_SUTA.Loc_No = PR_INP.Loc_No AND PR_SUTA.Div_No = PR_INP.Div_No AND PR_SUTA.Emp_No = PR_INP.Emp_No AND PR_SUTA.Pay_Date = PR_INP.Pay_Date WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND PR_INP.Pay_Date = CDATE(PaidOn) AND Def_Dept IN ('010', '011', '012')

SELECT SUM(PR_INP.Futa_5) + SUM(PR_SUTA.Amt_10) AS AMT, '66360' AS DEPT, CDATE(PaidOn) AS PayDate, 'ER Tax Exp:  FUTA/SUTA - Dept 13' AS Memo FROM PR_INP INNER JOIN PR_SUTA ON PR_SUTA.Loc_No = PR_INP.Loc_No AND PR_SUTA.Div_No = PR_INP.Div_No AND PR_SUTA.Emp_No = PR_INP.Emp_No AND PR_SUTA.Pay_Date = PR_INP.Pay_Date WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND PR_INP.Pay_Date = CDATE(PaidOn) AND Def_Dept IN ('013')

我已将 UNION ALL 用于其他查询,它们也可以正常工作:

SELECT SUM(PR_INP.Futa_5) + SUM(PR_SUTA.Amt_10) AS AMT, '67360' AS DEPT, CDATE(PaidOn) AS PayDate, 'ER Tax Exp:  FUTA/SUTA - Dept 10, 11, 12' AS Memo FROM PR_INP INNER JOIN PR_SUTA ON PR_SUTA.Loc_No = PR_INP.Loc_No AND PR_SUTA.Div_No = PR_INP.Div_No AND PR_SUTA.Emp_No = PR_INP.Emp_No AND PR_SUTA.Pay_Date = PR_INP.Pay_Date WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND PR_INP.Pay_Date = CDATE(PaidOn) AND Def_Dept IN ('010', '011', '012')
UNION ALL
SELECT SUM(Fica_5 + IIF(PR_MAST.Gross_Yr >= 200000.00, Medc_6, Medc_5) ), '63330', CDATE(PaidOn), 'ER Tax Exp: Federal, SS, Medicare- Dept 5, 6' FROM PR_INP INNER JOIN PR_MAST ON PR_MAST.Loc_No = PR_INP.Loc_No AND PR_Mast.Emp_No = PR_INP.Emp_No WHERE PR_INP.Loc_No = 2170 AND PR_INP.Div_No = 100 AND Pay_Date = CDATE(PaidOn) AND PR_INP.Def_Dept IN ('005', '006')

我也尝试将查询类型更改为传递查询,但仍然收到 ODBC--调用失败消息。

这里发生了什么?为什么单独运行的查询在联合在一起时也会产生 ODBC 错误?以及如何解决这个问题以便它运行?

【问题讨论】:

可能相关:***.com/questions/13177354/… 谢谢。我实际上是自己找到了那个帖子。我尝试了一切,但无法弄清楚为什么我的不工作,因为查询的每个部分都是单独工作的。 您是否通过 Pervasive Control Center 或其他 ODBC 工具运行 UNION ALL 查询?它是有效的还是会出错? 刚刚尝试过,是的,查询在 Pervasive Control Center 中有效。唯一的变化是我对日期进行了硬编码,而不是像在 Access SQL 中那样使用变量。 如果在 Access 中硬编码日期会发生什么? 【参考方案1】:

我不确定,但我不禁想知道这是否与使用 MEMO 作为列名有关,因为 MEMO 实际上是一种 ms 访问数据类型;从逻辑上讲,这应该无关紧要,但对于 Access,人们永远不会知道。

但是,尽管如此,您的查询不需要 UNION ALL 并且可以编写如下:

SELECT Sum(p.Futa_5) + Sum(s.Amt_10) as AMT, 
    iif(Def_Dept = '013', '66360', '67360') as DEPT, CDate(PaidOn) as PayDate, 
    'ER Tax Exp: FUTA/SUTA - Dept ' & iif(Def_Dept = '013', '13', '10, 11, 12') as [Memo]
FROM pr_inp p INNER JOIN pr_suta s ON p.Loc_No = s.Loc_No AND p.Div_No = s.Div_No 
    AND p.Emp_No = s.Emp_No AND p.Pay_Date = s.Pay_Date
WHERE p.Loc_No = 2170 AND p.Div_No = 100 AND p.Pay_Date = CDate(PaidOn) 
    AND Def_Dept IN ('010', '011', '012', '013')

在提问时,最好像我在此处所做的那样给表起别名,因为它使查询更易于理解,并且通常像我在这里一样添加换行符,以使回答者能够将您的代码复制到其他地方 - 我有由于没有换行符,在复制代码时会遇到一些麻烦。

如果将 from 子句中的 pr_inp 替换为子查询以仅返回 pr_inp 中您关心的那些行(将 where 子句移动到子查询中),此查询可能会运行得更快。例如

SELECT (as above)
FROM (SELECT * FROM pr_inp WHERE Loc_No = 2170 AND Div_No = 100) p
    INNER JOIN (as above)
WHERE p.Pay_Date = CDate(PaidOn) AND Def_Dept IN ('010', '011', '012', '013')

【讨论】:

【参考方案2】:

尝试排除故障的几种方法:

我刚刚看到@John Bingham 也提到了 MEMO……但无论如何我都会包括我的 cmets。

MEMO 是 Access 中的保留字 - 我怀疑这会导致 ODBC 错误,但如果您真的需要字段名,可以尝试将“MEMO”括在方括号中。您确实在您说有效的查询中使用了它 - 所以我不确定这是否是问题所在。

如果您创建两个单独的查询并将 UNION ALL 与这两个查询一起使用,查询是否有效?

【讨论】:

以上是关于为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Access 中对表的所有列进行 UNION ALL

简单的 MS Access SQL UNION ALL;如何包含自动注释列值?

SQL 中的 UNION 和UNION ALL 有啥区别?

SQL 中的 UNION 和UNION ALL 有啥区别?

为啥使用 UNION 运算符的相同查询比使用 UNION ALL 的成本低得多?

mysql数据库多个表union all查询并排序的结果为啥错误