Sql Access:将数据插入具有外键关系的两个表中

Sql Access:将数据插入具有外键关系的两个表中,sql,vba,ms-access,Sql,Vba,Ms Access,为了扩大规模,我创建了一个问题示例来复制我的问题 假设我有3张桌子: 人 | PID | PName | City | Autonumber Text Text 购买 |PurchaseNo | PID | Item | Autonumber Number Text 进口 |Pname| City | Item Text Text Text 因此,基本上,Person和Purchase表具有1对多的关系,每个人可以进行1对多的购买。PID是人员的主键

为了扩大规模,我创建了一个问题示例来复制我的问题

假设我有3张桌子:

| PID      | PName | City  |
 Autonumber  Text    Text
购买

|PurchaseNo | PID  | Item |
 Autonumber  Number  Text
进口

|Pname| City | Item
 Text   Text   Text
因此,基本上,Person和Purchase表具有1对多的关系,每个人可以进行1对多的购买。PID是人员的主键,同时也是采购表的FK。所以,如果我直接输入数据,一切都会很好。但是每天早上都有数据,我必须导入。它以导入表的形式出现,导入表的格式与我所展示的一样

因此,我的问题是如何将导入的数据表分发给两个表,同时保持它们的1对多关系的完整性

我采取的一种方法是尝试使用@@identity,下面是我在vba中使用的代码:

 Option Compare Database

Public Sub IMPORTRE()

  On Error GoTo errHandler
    Dim wrk As DAO.Workspace
    Dim db As DAO.Database
    Dim lngInvoiceID As Long

    Set wrk = DBEngine.Workspaces(0)
    Set db = wrk.OpenDatabase(CurrentDb.Name)
    With wrk
      .BeginTrans
      db.Execute "INSERT INTO Person SELECT PName,City FROM Import", dbFailOnError
      lngInvoiceID = db.OpenRecordset("SELECT @@IDENTITY")(0)
      db.Execute "INSERT INTO Purchase SELECT " & lngInvoiceID & " As PID, Item FROM Import ", dbFailOnError
      .CommitTrans
      Debug.Print "Inserted Invoice header and detail for Invoice " & lngInvoiceID
    End With

exitRoutine:
    If Not (db Is Nothing) Then
       db.Close
       Set db = Nothing
    End If
    Set wrk = Nothing
    Exit Sub

errHandler:
    MsgBox Err.Number & ": " & Err.Description, vbExclamation, "Error in transaction"
    wrk.Rollback
    Resume exitRoutine

End Sub
除了一件事,它工作得很好,很漂亮。PID将始终是最后导入的值


所以我的问题是,我如何着手解决这个问题。这是我的密码吗?还是我把一个简单的问题复杂化了?重申一下,我想做的是将导入表中的数据插入到具有外键关系的两个表中。

假设您的名称是唯一的,您可以通过两个查询来完成此操作。第一个从导入工作表中插入
Person
表中不存在的人员

INSERT INTO Person ( PName, City )
SELECT PName, City
FROM Import
WHERE not Exists (Select PName, City from Person WHERE PName = Import.PName);
对于第二个查询,您需要使用联接。这将允许您在一条语句中获得现有用户和项目的PID

INSERT INTO Purchase ( PID, Item )
SELECT Person.PID, Import.Item
FROM Import INNER JOIN Person ON Import.PName = Person.PName;

在创建PName之前,需要检查PName是否存在。如果存在,请使用该键。如果没有,请创建它并使用新密钥。这就引出了一个问题:pName是唯一的吗?如果是的话,为什么还要为必须查找的数字FK而烦恼呢?如果不是,这也不是太可行,因为你不知道pID。