【问题标题】:Access - FULL OUTER JOIN without using UNION so recordset is updateable访问 - 不使用 UNION 的 FULL OUTER JOIN 所以记录集是可更新的
【发布时间】:2011-08-14 03:22:03
【问题描述】:

如果我在 Access 中将 UNION 用于子表单记录集,则不允许使该记录集可更新。

问题是,我需要能够更新记录集。

我有两张表——一张是员工列表(Employees)。另一个是记录每个员工当天关闭的票数。因此,该表 (INCTech) 使用 EmployeeID 和 Date 作为联合主键,因为每个员工在给定日期只能有一条记录。

我无法使用 LEFT OUTER JOIN 来检索完整的员工列表,因为它会排除在 INCTech 中在给定日期以外的日期有记录的任何员工。这不起作用:

SELECT INCTech.EmployeeID, INCTech.Assigned, INCTech.Closed, INCTech.Submitted,
INCTech.StillOpen, INCTech.TheDate, Employees.FirstName, Employees.LastName
FROM Employees LEFT JOIN INCTech ON Employees.EmployeeID = INCTech.EmployeeID
WHERE Employees.GroupID = 8 AND (INCTech.TheDate = #4/15/2011# OR 
INCTech.TheDate IS NULL)

因为如果员工的记录与 2011 年 4 月 15 日不同,则他们不满足两个日期条件中的任何一个 - 日期不再为 NULL,但它也不是给定的日期。

我的有效查询是:

SELECT Employees.EmployeeID, Employees.FirstName, Employees.LastName,
Employees.FirstName & " " & Employees.LastName AS FullName, INCTech.TheDate,
INCTech.Assigned, INCTech.Closed, INCTech.Submitted, INCTech.StillOpen,
Employees.GroupID
FROM Employees
LEFT OUTER JOIN INCTech ON
Employees.EmployeeID=INCTech.EmployeeID 
WHERE (INCTech.TheDate)=Calendar.Value AND Employees.GroupID = ddlGroup.Value
UNION
SELECT Employees.EmployeeID, Employees.FirstName, Employees.LastName, 
Employees.FirstName & " " & Employees.LastName AS FullName, NULL AS TheDate, 
NULL AS Assigned, NULL AS Closed, NULL As Submitted, NULL As StillOpen, 
Employees.GroupID 
FROM Employees 
LEFT OUTER JOIN INCTech ON Employees.EmployeeID=INCTech.EmployeeID 
WHERE Employees.EmployeeID NOT IN 
(SELECT INCTech.EmployeeID FROM INCTech WHERE INCTech.TheDate=Calendar.Value) 
AND Employees.GroupID = ddlGroup.Value

但由于我必须使用 UNION 才能工作,因此生成的记录集是只读的。这是行不通的 - 我需要能够为每个员工的日常记录修改或添加数据。

救命!

【问题讨论】:

    标签: sql ms-access union outer-join


    【解决方案1】:

    用这个查询作为它的记录源构建一个表单:

    SELECT e.EmployeeID, Date() AS TheDate, e.LastName, e.FirstName
    FROM Employees AS e
    ORDER BY e.LastName, e.FirstName;
    

    添加一个使用 INCTech 作为记录源的子表单。

    使用 EmployeeID;TheDate 作为链接子字段和链接主字段。

    选择单个表单作为子表单的默认视图。 Set Navigation Buttons = No。将 Cycle 属性设置为 Current Record。

    然后对于主表单中的任何员工记录,如果有一行,您的子表单将显示匹配的 INCTech 行(同一员工,同一日期),如果不存在,则允许您添加一行。

    但您可能希望编辑今天以外日期的 INCTech 数据。在这种情况下,您可以将未绑定的文本框控件添加到主窗体的标题中,例如 txtWhichDate,并允许用户输入日期值。在这种情况下,您可以调整主窗体的查询以引用文本框值而不是 Date()。

    SELECT e.EmployeeID, Forms!YourFormName!txtWhichDate AS TheDate, e.LastName, e.FirstName
    FROM Employees AS e
    ORDER BY e.LastName, e.FirstName;
    

    或者你可以在txtWhichDate的更新后事件中添加代码来更新记录源以匹配。

    【讨论】:

      【解决方案2】:

      我认为问题在于您的 WHERE 条件将 INCTech 表中的结果限制为与 Calendar.Value 匹配的记录。

      您可以尝试创建一个单独的查询来从 INCTech 检索记录并在查询中应用 WHERE INCTech.TheDate = Calendar.Value 子句。

      在您的主查询中,使用 LEFT JOIN 直接引用此查询而不是 INCTech 表。

      这应该返回来自 Employee 的记录,并显示在基于 INCTech 表的查询中匹配的每个员工记录的相关详细信息。

      【讨论】:

        【解决方案3】:

        您将无法在记录集中包含多个表并使其可更新。您的表单应编辑员工记录表并链接到 INCTech 表作为子表单。

        否则,您可以创建一个查询来显示包含联合和多个表的所有数据,但您必须在两个表上编写更新语句,以便在更改行时执行。您需要根据 EmployeeID 和 EmployeeID 以及 TheDate 或 INCTech 表过滤要更新的行。在 Access 中搜索更新多个表。

        这将解决您最关心的查询问题:

        Select E.* 
          , I.TheDate
        from Employees as E
        Left Outer Join (
          Select * 
          from INCTech 
          Where TheDate = #4/15/2001#) as I
        on E.EmployeeID = I.EmployeeID
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-02-28
          • 2017-08-12
          • 1970-01-01
          • 1970-01-01
          • 2015-12-21
          • 1970-01-01
          • 2021-06-09
          相关资源
          最近更新 更多