【问题标题】:ms access query (ms access freezes)ms 访问查询(ms 访问冻结)
【发布时间】:2019-02-18 14:15:25
【问题描述】:

我有这份报告,需要为每个人添加总计(红色圆圈) existing report

new report

我无法更改现有报告,因此我将数据从 MS SQL 导出到 MS Access 并在那里创建一个新报告。我让它为一名员工工作,但在处理多名员工的查询时遇到了麻烦。

此查询提取数据用作输入:

SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[EMP_ID])=376) And (([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));

此查询填充报告:

SELECT *
FROM TIME1
WHERE RCD_NUM = (SELECT Max(RCD_NUM) FROM [TIME1] UQ WHERE UQ.PPERIOD = [TIME1].PPERIOD AND UQ.PC = [TIME1].PC);

问题是如果我像这样从第一个查询中删除 EMP_ID

SELECT [TIME].[RCD_NUM], [TIME].[EMP_ID], [TIME].[PPERIOD], [TIME].[PRUN], [TIME].[TDATE], [TIME].[PC], [TIME].[RATE], [TIME].[HOURS], [TIME].[AMOUNT], [TIME].[JOB_ID], [TIME].[UPDATED], [TIME].[UPDATED_BY], [TIME].[LOG_DATE], [TIME].[ORIGINAL_REC_NUM]
FROM [TIME]
WHERE ((([TIME].[TDATE])<=#12/31/2006# And ([TIME].[TDATE])>=#1/1/2006#) And (([TIME].[PC])<599));

那么第二个查询不起作用并且在运行此查询时 ms 访问冻结。

有什么帮助/想法吗?

【问题讨论】:

    标签: sql ms-access


    【解决方案1】:

    警告:我不会假装知道问题的确切原因,但我不得不在 Access 中反复重构查询以使它们工作,即使原始 SQL 语句在关于语法和逻辑。有时为了避免 Access 中的错误,我不得不处理一系列查询。访问通常相当愚蠢,并且会简单地(重新)执行查询和子查询,而无需优化。在其他时候,Access 会尝试通过执行一些内部优化来组合查询,但有时这些会引入令人沮丧的错误。像名称更改或列重新排序这样简单的事情可能是正常查询与崩溃或冻结 Access 的查询之间的区别。


    首先考虑:

    • 能否将数据保留在 SQL Server 上并链接到 Access 中的结果(而不是将其导出/导入到 Access 中)?即使您需要或更喜欢使用 Access 来创建实际报告,您也可以使用 SQL Server 的所有功能来查询数据——它可能会更少错误且更高效。
      • 常见的最佳实践是创建 SQL Server 存储过程,该过程仅返回您在 Access 中需要的数据。在 Access 中创建传递查询以检索数据,但所有数据操作均在服务器上执行。
    • 也许这只是一个性能问题,通过[EMP_ID] 限制集合选择了一个小子集,但整个表足够大,可以“冻结”访问。
      • 在终止进程之前,您让 Access 保持冻结状态多长时间?要有耐心......就像很多很多分钟(或几个小时)。早上开始,午餐后检查。 :) 它最终可能会返回一个结果集。这并不意味着它是可以容忍的或没有其他解决方案,但了解它最终是否返回数据可能很有用。
      • 有多少可能的记录?
      • 导入的数据是否正确索引?为所有关键字段以及在 WHERE 子句中使用的字段添加索引。
      • 数据库是位于网络共享上还是本地?尝试将数据库复制到本地驱动器。

    其他提示:

    • 对于 WHERE 子句中的日期,请尝试使用 BETWEEN 运算符。

    尝试通过在 FROM 子句而不是 WHERE 子句中执行连接来重构“第二个”查询。在执行此操作时,您可能还希望将子查询保存为命名查询(就像保存 [TIME1] 一样)。无论查询是否保存或嵌入到另一个语句中,都可以改变 Access 的行为(请参阅警告),即使结果应该相同。

    这是一个带有嵌入式聚合查询的版本。请注意所有列引用如何使用源进行限定。一些原始查询的列没有作为列名前缀的源别名。记住警告......这种挑剔的细节会影响访问行为。:

    SELECT TIME1.*
    FROM TIME1 INNER JOIN
      (SELECT UQ.PPERIOD, UQ.PC, Max(UQ.RCD_NUM) As Max_RCD_NUM
       FROM [TIME1] UQ
       GROUP BY UQ.PPERIOD, UQ.PC) As TIMEAGG
      ON (TIME1.PPERIOD = TIMEAGG.PPERIOD) And (TIME1.PC = TIMEAGG.PC)
        AND (TIME1.RCD_NUM = TIMEAGG.Max_RCD_NUM)
    

    【讨论】:

    • 您好,非常感谢您的建议。出于安全原因(至少现在),我宁愿在 Access(本地)中执行此操作,因为我没有设计原始的 MS SQL 数据库。当我让运行我的查询时,任务管理器显示“访问未响应......”记录数应该不是问题,因为第一个查询只选择了大约 3500 条记录。我尝试了您的查询,它看起来很有希望 - 它不会冻结,提供一些记录,不幸的是它还在打开和编辑选项中给我一个错误消息“FROM 子句中的语法错误”,我不能使用数据或编辑这个查询。
    • 嗯...我不明白查询如何返回记录和“在 FROM 子句中”的错误。如果 FROM 子句中有错误,则根本不应该返回任何记录。另外,您“不能使用数据或编辑此查询”是什么意思?您的意思是不能编辑 SQL 或者一旦数据表中返回的数据就不能编辑?如果您指的是数据表中的数据,那是正确的——它是不可更新的,因为它连接到一个聚合查询,但据我所知,这并不重要,因为这只是为了报告。
    • 是的,它返回记录并同时在其顶部显示错误消息。当我在错误消息上单击“确定”时,记录消失(记录集窗口关闭)。当我在编辑中打开查询时,同样会发生 - 错误消息,单击,关闭所有内容。
    • 令人困惑。我从来没有经历过这种特殊的行为。您是否尝试过修复和压缩数据库?正如我在答案中提到的,尝试将嵌入式子查询保存并运行为命名查询。它运行没有错误吗?如果可行,则编辑“第二个”查询以加入新保存的查询而不是嵌入语句。
    • 我能够生成并运行报告您的查询,那里没有错误消息。但结果不正确 - 一些员工缺失(75 人中有 27 人)、工资期缺失、特定员工和期间的金额不正确。将嵌入式子查询作为命名查询运行没有错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多