如何在主/明细关系中插入记录

时间:2009-06-18 15:05:27

标签: database delphi master-detail

我有两张桌子:

OutputPackages(master)

|PackageID|

OutputItems(详细信息)

|ItemID|PackageID|

OutputItems在PackageID列上设置了一个名为“idxPackage”的索引。 ItemID设置为自动增量。

这是我用来在这些表中插入主人/细节的代码:

//fill packages table
for i := 1 to 10 do
begin
  Package := TfPackage(dlgSummary.fcPackageForms.Forms[i]);

if Package.PackageLoaded then
begin
  with tblOutputPackages do
  begin
    Insert;
    FieldByName('PackageID').AsInteger := Package.ourNum;
    FieldByName('Description').AsString := Package.Title;
    FieldByName('Total').AsCurrency := Package.Total;
    Post;
  end;

  //fill items table
  for ii := 1 to 10 do
  begin
    Item := TfPackagedItemEdit(Package.fc.Forms[ii]);
    if Item.Activated then
    begin
      with tblOutputItems do
      begin
        Append;
        FieldByName('PackageID').AsInteger := Package.ourNum;
        FieldByName('Description').AsString := Item.Description;
        FieldByName('Comment').AsString := Item.Comment;
        FieldByName('Price').AsCurrency := Item.Price;
        Post; //this causes the primary key exception
      end;
    end;
  end;
end;

只要我不搞乱IDE中的MasterSource / MasterFields属性,这就可以正常工作。但是一旦我设置它并运行此代码,我会收到一条错误消息,说我有一个重复的主键'ItemID'。

我不确定发生了什么 - 这是我第一次涉及到主/细节,所以可能会出现问题。我正在为这个项目使用ComponentAce的绝对数据库。

如何正确插入?

更新

好的,我删除了我的数据库中的主键约束,我看到由于某种原因,OutputItems表的自动增量功能不像我预期的那样工作。以下是运行上述代码后OutputItems表的外观:

ItemID|PackageID|
1     |1        |
1     |1        |
2     |2        |
2     |2        |

我仍然不明白为什么所有ItemID值都不是唯一的......有什么想法吗?

3 个答案:

答案 0 :(得分:2)

使用insert而不是append在items表上的行为是否有所不同?我的猜测是细节上的附加“看到”一个空的数据集,所以自动递增逻辑从一个,下一个记录二开始,等等,即使这些值已被分配...只是为了一个不同的主记录

我过去使用的一个解决方案是创建一个名为UniqueNums的新表,该表持久存储我将要使用的下一个可用记录ID号。当我使用一个数字时,我会锁定该表,增加值并将其写回然后解锁并使用。这可能会让您了解您遇到的具体问题。

答案 1 :(得分:0)

首先,在我看来,通过代码冲突自动增量和设置ID的想法。明确的路径是在代码中自己生成密钥。特别是对于需要主/细节插入的多用户应用程序,很难无法为细节插入正确的密钥。

因此,按代码生成ID。设计表时,将ID字段设置为主键但不设置自动增量。如果我没有弄错,Append用于操作。

此外,您似乎在启用可视控件时进行迭代? (Item.Activated)。但该操作本质上是一个批处理过程。对于GUI性能,您应该考虑,禁用已连接的数据库控件,然后执行该操作。作为主/详细范围,这可能是另外两个游标没有按预期迭代的问题。

答案 2 :(得分:0)

您是否尝试使用编辑替换附加/插入?
并跳过“FieldByName('PackageID')。AsInteger:= Package.ourNum;”线。

我认为M / D关系会根据需要自动附加详细记录,还会设置详细信息表的主键。

这也可能是重复主键错误的原因。当您尝试追加/插入另一个时,记录已由M / D关系创建。