【问题标题】:Are Append Queries in a self joining table possible是否可以在自联接表中追加查询
【发布时间】:2016-12-22 09:45:52
【问题描述】:

我有 tblEmployee 包含 3 个字段:

  1. ID:自动编号
  2. Name:文字
  3. Supervisor: Number [在 tblEmployee 中查找]

我希望将来自tblNewEmployees 的新数据附加到该表中,该数据与上一个表具有完全相同的结构。

如果我将 ID 字段作为自动编号,可以这样做吗?

我尝试了各种查询(例如,首先仅在步骤 1 中附加名称字段,然后尝试使用第二个更新查询来获取主管)但都产生了垃圾,因此我的问题是在第一名。

【问题讨论】:

  • 您面临的问题是 tblNewEmployees 的 ID 值已存在于 tblEmployee 中吗?
  • 除其他外......是的。虽然情况并非如此,但我也无法获得正确引用 ID 的更新

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


【解决方案1】:

我想它可以在您的结构(邻接列表模型)中以迭代方式完成,即在树的顶部添加员工,查询数据库以获取他们自动生成的 id,然后使用先前查询的 id 将员工添加到下一个级别,然后为每个级别重复。

虽然可能,但是否可取?大概每个员工都已经有一个唯一的 id,例如工资单号、社会保险号等。如果不确定,请询问工资单号。

在生成员工 ID 时删除数据库的依赖关系可能会使您从上述迭代过程中解脱出来。插入内容最好是确定性的、可预测的、一次性可脚本化的等。

要考虑的另一件事是,当您可能需要层次结构时,您可能正在对树结构进行建模。 Celko 曾经举过的例子:军队是一个等级制度,因为如果你射杀了你的中士,你仍然必须听从上尉的命令;另一方面,河流系统是树,因为如果您的大坝是一条支流,那么所有下游支流都会干涸。

在我看来,在您的设计中,当主管离开(从表中删除)时,您会留下一个无人监督的员工(缺少数据,因此数据完整性被破坏),而您想要下一位高级员工取代他们的位置(层次结构)。如果工作(即再次迭代),您的结构中的更新可能会很多。

虽然邻接表模型可能很直观,但在 SQL DML 中使用它并不总是最容易的。考虑其他模型,例如嵌套集。也就是说,对于 Access,SQL DML 几乎总是很痛苦,因为它不支持存储过程、触发器等中的过程 SQL 代码;由于“不可更新的查询”(视图)限制,即使是简单的更新也会失败。因此,像往常一样,我必须建议您尽可能考虑使用功能更强大的 DBMS。

【讨论】:

  • 感谢您的回答!如果只是为了“Celko”的报价,我会投票两次。但是,无论好坏,我现在都坚持使用 Access。我正在建立的层次结构不会是如果有人被删除,就必须有一个新的主管。我使用员工/主管来保持解释简单。我映射的信息是分层的,但我们本质上是使用数据库收集有关层次结构的知识,所以我们没有确定性密钥(无论是人还是层次结构)
  • ( cc: @rohrl77 ) 不需要迭代代码。无需更改关系模型。无需切换数据库。详情请见my answer。
  • @onedaywhen - “您的答案通过遵循我的建议'删除数据库在生成员工 ID 时的依赖关系'”来避免迭代代码” - 不,tblEmployee.ID 是场景 2 中自动生成的 AutoNumber。
  • @onedaywhen - “您不能在 Access 中使用 DELETE 后跟 UPDATE 来定义过程、触发器等” - 在 Access 2010 中(每个问题标签)和较新的版本,您可以使用 After Delete data macro(如 this)来更新层次结构。
  • @GordThompson:也许我没有遵循您的论点(不是来这里争​​论的-叹息),但在我看来,您在场景 2 中使用了迭代方法,例如插入后跟更新。请参阅我的回答以获取适当的措辞:“SQL DML 几乎总是很痛苦,因为它不支持存储过程、触发器等中的过程 SQL 代码”——如果您认为我的陈述有误,请随时纠正它。
【解决方案2】:

是的,当目标表具有自动编号 ID 时,可以合并这两个表。有两种可能的情况:

场景一:两个表的ID值不重叠

[tblEmployee]
ID  Name        Supervisor
--  ----------  ----------
 1  Director A            
 2  Manager A            1
 3  Worker A             2

[tblNewEmployees]
ID   Name        Supervisor
---  ----------  ----------
101  Director B            
102  Manager B          101
103  Worker B           102

由于 Access 数据库引擎允许我们将任意值插入自动编号列,因此这种情况很简单。就……

INSERT INTO tblEmployee (ID, [Name], Supervisor)
SELECT ID, [Name], Supervisor FROM tblNewEmployees

...我们完成了:

[tblEmployee]
ID   Name        Supervisor
---  ----------  ----------
  1  Director A            
  2  Manager A            1
  3  Worker A             2
101  Director B            
102  Manager B          101
103  Worker B           102

场景 2:两个表之间的通用 ID 值

[tblEmployee]
ID  Name        Supervisor
--  ----------  ----------
 1  Director A            
 2  Manager A            1
 3  Worker A             2

[tblNewEmployees]
ID   Name        Supervisor
--  ----------  ----------
 2  Director B            
 5  Manager B            2
 7  Worker B             5

在这种情况下,我们需要在插入新行时将旧 ID 值映射到新 ID 值。为此,向 [tblEmployee] 添加一个新列

ALTER TABLE tblEmployee ADD oldID LONG

然后插入新行,将 tblNewEmployees.ID 放入 tblEmployee.oldID

INSERT INTO tblEmployee (oldID, [Name])
SELECT ID, [Name] FROM tblNewEmployees

给我们

[tblEmployee]
ID  Name        Supervisor  oldID
--  ----------  ----------  -----
 1  Director A                   
 2  Manager A            1       
 3  Worker A             2       
 4  Director B                  2
 5  Manager B                   5
 6  Worker B                    7

然后我们可以用新的 ID 值更新 Supervisor 列

UPDATE 
    (
        tblEmployee emp
        INNER JOIN
        tblNewEmployees new
            ON emp.oldID = new.ID
    )
    INNER JOIN
    tblEmployee emp2
        ON new.Supervisor = emp2.oldID
SET emp.Supervisor = emp2.ID

生产

[tblEmployee]
ID  Name        Supervisor  oldID
--  ----------  ----------  -----
 1  Director A                   
 2  Manager A            1       
 3  Worker A             2       
 4  Director B                  2
 5  Manager B            4      5
 6  Worker B             5      7

如果需要,我们可以删除 [oldID] 列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2014-01-07
    • 2015-09-25
    • 1970-01-01
    • 2012-08-19
    • 2017-08-08
    相关资源
    最近更新 更多