2

我有两张桌子:

输出包(主)

|PackageID|

输出项目(详细)

|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 值都不是唯一的......有什么想法吗?

4

3 回答 3

2

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

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

于 2009-06-18T21:24:02.507 回答
0

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

所以通过代码生成一个ID。设计表格时,将 ID 字段设置为主键但不自动递增。如果我没记错的话 Append 用于操作。

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

于 2009-06-21T13:23:48.807 回答
0

您是否尝试过用 Edit 替换 Append/Insert?
并跳过“FieldByName('PackageID').AsInteger := Package.ourNum;” 线。

我认为 M/D 关系会根据需要自动追加明细记录,并设置明细表的主键。

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

于 2010-05-16T07:14:34.613 回答