【问题标题】:Cannot edit a field on a query无法编辑查询中的字段
【发布时间】:2021-01-28 05:53:52
【问题描述】:

这是我第一次在这个论坛上找不到我的问题的答案,所以我决定注册并发布它。

我在编辑查询中的字段时遇到问题。我有 2 个要从中提取数据的表,但我需要今年和去年(以季度为单位)第二个表中的 2 组数据。我需要能够编辑选定的列(即选择一个人)。

成员表(选择是/否字段,默认为否)

| ID | Name | Selected | Status |
|  1 | Bob  |    No    |    M   |
|  2 | Sam  |    No    |    M   |

StampDues 表

| ID | DuesYear | Q1_Date | Q2_Date | Q3_Date | Q4_Date |
|  1 |   2020   |  1/1/20 |  4/1/20 |  7/1/20 | 10/1/20 |
|  1 |   2021   |  1/2/21 |  2/1/21 |         |         |
|  2 |   2020   |  1/2/20 |  4/2/20 |  7/2/20 | 10/2/20 |
|  2 |   2021   |  1/2/21 |         |         |         |

我正在查找当前年份和去年日期的汇总,但随后需要能够“选择”一个人。

|Selected|Name |Last_Q1|Last_Q2|Last_Q3|Last_Q4|This_Q1|This_Q2|This_Q3|This_Q4|
|    #   | Bob |1/1/20 |4/1/20 |7/1/20 |10/1/20|1/2/21 |2/1/21 |       |       |
|    #   | Sam |1/2/20 |4/2/20 |7/2/20 |10/2/20|1/2/21 |       |       |       |

我最初尝试了 join 语句,但无法选择人员。我现在正在使用更简单的代码,但仍然无法选择一个人。

SELECT
  Selected,
  Name,
  (SELECT Q1_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)-1) AS [Last Q1],
  (SELECT Q2_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)-1) AS [Last Q2],
  (SELECT Q3_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)-1) AS [Last Q3],
  (SELECT Q4_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)-1) AS [Last Q4],

  (SELECT Q1_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)) AS [This Q1],
  (SELECT Q2_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)) AS [This Q2],
  (SELECT Q3_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)) AS [This Q3],
  (SELECT Q4_Date FROM StampDues WHERE [Member ID] = Members.MemberID AND DuesYear = year(now)) AS [This Q4]
FROM Members
  WHERE GetIsMemberStatus(Status) = True
  ORDER BY Name;

GetIsMemberStatus 是我创建的一个自定义函数,它返回 True 或 False。这似乎不是问题,因为它正在正确过滤名称。

作为一个注释,我使用这个查询作为一个连续子表单的控制源。我可以让子表单与日期的大量 dlookup 字段一起正常工作,但这填充速度很慢。我更喜欢 SQL 查询,因为它们似乎填充得更快。

【问题讨论】:

  • 保存计算数据通常是不必要的,并且存在数据不同步的风险。没有涉及聚合查询的更新。如果可以计算更新,应该可以在需要的时候计算。如果您真的必须保存,替代方案涉及域聚合函数和/或 VBA。
  • 查询呈现不可更新且不符合 UPDATE 操作的其他原因。您在查询中有不在表结构中的字段名称。我假设 ID 字段实际上命名为 MemberID 和 Member ID。建议不要在字段名称中使用空格。
  • 我被计算出来的语句弄糊涂了。从表中选择的值均未计算,它们都是实际值。我只需要同时看到它们,并且能够“选择”一个人。从那里,一些 VBA 代码循环遍历成员表,并进一步处理选定字段设置为“是”的成员。我也知道字段名称没有空格规则,我只是在制作该表之后才知道这一点,以及很多代码。
  • 计算或连接表,关键是您的查询不可编辑,不能在 UPDATE 操作中使用。当需要在查询或报表中显示时,可以在查询中计算“选定”值。最新版本的查询显示计算字段。
  • @dms292 请检查答案,让我知道它是否有效。最美好的祝愿:)

标签: sql ms-access ms-access-2010 jet


【解决方案1】:

要了解您正在处理的内容,我会

  1. 为去年的 StampDues 创建一个查询 - q_LastYearDues
SELECT [Member ID] as MemberID, Q1_Date as [Last Q1], Q2_Date as [Last Q2], Q3_Date as [Last Q3], Q4_Date as [Last Q4]
FROM StampDues WHERE DuesYear = year(now)-1
  1. 为今年的 StampDues 创建一个查询 - q_ThisYearDues
SELECT [Member ID] as MemberID, Q1_Date as [This Q1], Q2_Date as [This Q2], Q3_Date as [This Q3], Q4_Date as [This Q4]
FROM StampDues WHERE DuesYear = year(now)
  1. 创建您的主查询
SELECT a.Selected, a.Name, b.[Last Q1], b.[Last Q2],b.[Last Q3],b.[Last Q4]
,c.[This Q1], c.[This Q2],c.[This Q3],c.[This Q4]
From Members a 
left join q_LastYearDues b on a.MemberID=b.MemberID
left join q_ThisYearDues c on a.MemberID=c.MemberID

通过这种方式,您可以独立运行每个查询以找出问题所在 - 可能是将文本值连接到整数或类似的东西。前 2 个查询应该是可更新的。

还要确保在表上定义主键,因为有时这会使表变为只读。

【讨论】:

  • 这看起来很有希望。主键定义在所有表中。如果我只使用第一个连接,我不会收到任何错误,并且所选字段是可编辑的(也删除选择 c.*)。当我添加第二个连接时,我收到错误“查询表达式'a.MemberID=b.MemberID left join q_ThisYearDues c on a.MemberID=c.MemberI' 中的语法错误(缺少运算符)”。是的,它在最后切断了 MemberID 的最后一个字符。
  • 这很奇怪。如果您在 MS Access 查询中运行它来测试它,那么这种情况永远不会出现。我会将所有 3 个查询隔离在他们自己的查询中,最后加入 2 个,这样您就可以清楚地调试正在发生的事情。基本上为每个查询创建一个新查询,忽略添加表对话框,转到 SQL 视图,然后按照我的方式粘贴查询。我在回答中稍微修改了它们以反映您的确切字段。
  • 我就是这样做的,我首先在查询中测试它们。 q_LastYearDues 和 q_ThisYearDues 单独工作。它们在单独加入第三个查询时也可以工作(删除对另一个查询的所有引用)。如果 then 都在查询中(从上面的文本中复制),我会收到前面提到的那个奇怪的错误。
  • 如果会员有可能没有去年的记录,会有什么不同吗?今年的新成员,去年不会有记录。
  • 我会尝试与设计视图中的成员一起单独运行正常的 2 个查询。我不明白为什么主查询会出错,除非您对空值进行摘要。第三个查询不是聚合。左连接的唯一原因是因为我们假设成员表包含今年和去年的所有成员。老会员今年可能没有缴纳会费,而今年的新会员去年没有缴纳会费。你得到的将是所有成员填写的内容,有时是旧成员会费,有时是新成员会费,你会得到空值
【解决方案2】:

我认为您能够使其正常工作的唯一方法是在临时表中执行 Make-Table 查询 (SELECT xxx INTO tempTable FROM xxx),然后将布尔值“Selected”列插入查询。您每次都需要删除临时表并使用 Make-Table 查询重新创建它。

然后您可以将临时表绑定到连续表格。您需要代码或 SQL 才能将输入的数据重新输入数据库。

【讨论】:

    【解决方案3】:

    从您说的那句话中,“我正在查找当前年份和去年日期的汇总,但随后需要能够'选择'一个人。”我的理解是你想要MemberID。如果是这样,那么我可能会为您提供解决方案。
    SQL

    DECLARE @MEMBER TABLE( ID INT, [NAME] VARCHAR(30),SELECTED BIT,[Status] VARCHAR(2));
    DECLARE @StampDues TABLE( ID INT,DuesYear VARCHAR(10),Q1_Date DATE,Q2_Date DATE,Q3_Date DATE,Q4_Date DATE);
    INSERT INTO @MEMBER VALUES(1,'Bob',0,'M');
    INSERT INTO @MEMBER VALUES(2,'Sam',1,'M');
    
    INSERT INTO @StampDues VALUES(1,'2020','1/1/20','4/1/20','7/1/20','10/1/20');
    INSERT INTO @StampDues VALUES(1,'2021','1/2/21','2/1/21',null,null);
    INSERT INTO @StampDues VALUES(2,'2020','1/2/20','4/2/20','7/2/20','10/2/20');
    INSERT INTO @StampDues VALUES(2,'2021','1/2/21',null,null,null);
    
    WITH summary AS (
    Select s.*,m.NAME,m.SELECTED,
           ROW_NUMBER() OVER(PARTITION BY m.ID 
                                     ORDER BY s.DuesYear DESC) AS rn
    FROM @MEMBER m
    INNER JOIN @StampDues s ON  m.ID=s.ID
    )
    SELECT s.ID MEMBERID,s.NAME,s.SELECTED,s.Q1_Date Last_Q1,s.Q2_Date Last_Q2,
           s.Q3_Date Last_Q3,s.Q3_Date Last_Q4,
           s1.Q1_Date This_Q1,s1.Q2_Date This_Q2,
           s1.Q3_Date This_Q3,s1.Q3_Date This_Q4
    FROM summary s
    INNER JOIN summary s1 ON s1.rn=1 and s.rn=2 and s.ID=s1.ID
    

    要更新条件你可以在WITH summary AS(......)=>结束后这样尝试

    UPDATE @MEMBER SET SELECTED=1 WHERE ID IN
    (SELECT s.ID MEMBERID
        --   ,s.NAME,s.SELECTED,s.Q1_Date Last_Q1,s.Q2_Date Last_Q2,
        --   s.Q3_Date Last_Q3,s.Q3_Date Last_Q4,
           --s1.Q1_Date This_Q1,s1.Q2_Date This_Q2,
        --   s1.Q3_Date This_Q3,s1.Q3_Date This_Q4
    FROM summary s
    INNER JOIN summary s1 ON s1.rn=1 and s.rn=2 and s.ID=s1.ID
    WHERE s.SELECTED=0 --your condition
    )
    SELECT * FROM @MEMBER;--To Check the data is Updated
    

    注意:现在,如果您想更新您的MEMBER 表,您可以使用MEMBERID,您还可以根据您的要求操作查询。请检查代码并告诉我。查询是在 SQL SERVER 16 上编写的。

    【讨论】:

    • 它不适用于MS-Access 数据库。
    • 好的。感谢您纠正我@Harun24HR。但我的代码在 SQL Server 中。最良好的祝愿。:)
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    相关资源
    最近更新 更多