Как вставить записи в отношения мастер / деталь - PullRequest
2 голосов
/ 18 июня 2009

У меня есть две таблицы:

Пакеты вывода (мастер)

|PackageID|

OutputItems (подробно)

|ItemID|PackageID|

OutputItems имеет индекс idxPackage, установленный в столбце PackageID. 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;

Это работает нормально, если я не связываюсь со свойствами MasterSource / MasterFields в IDE. Но как только я установил его и запустил этот код, я получил сообщение об ошибке, в котором говорится, что у меня есть дубликат первичного ключа ItemID.

Я не уверен, что происходит - это мой первый набег на мастера / детали, поэтому что-то может быть неправильно настроено. Я использую Абсолютную базу данных ComponentAce для этого проекта.

Как мне заставить это вставить правильно?

Обновление

Хорошо, я удалил ограничение первичного ключа в моей базе данных и вижу, что по какой-то причине функция автоинкремента в таблице OutputItems работает не так, как я ожидал. Вот как выглядит таблица OutputItems после выполнения приведенного выше кода:

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

Я до сих пор не понимаю, почему все значения ItemID не уникальны .... Есть идеи?

Ответы [ 3 ]

2 голосов
/ 19 июня 2009

По-другому ли работает вставка, а не добавление в таблицу элементов? Я предполагаю, что добавление к детали «видит» пустой набор данных, поэтому логика автоинкремента начинается с одной, следующей записи с двумя и т. Д., Даже если эти значения уже были назначены ... просто другой основной записи .

Одним из решений, которое я использовал в прошлом, было создание новой таблицы с именем UniqueNums, в которой сохранялся следующий номер идентификатора доступной записи, который я собирался использовать. Поскольку я использовал число, я блокировал эту таблицу, увеличивал значение и записывал его обратно, затем разблокировал и использовал. Это может помочь вам решить конкретную проблему, с которой вы столкнулись.

0 голосов
/ 16 мая 2010

Вы пытались заменить Добавить / Вставить на Редактировать?
И пропустите "FieldByName ('PackageID'). AsInteger: = Package.ourNum;" линия.

Я думаю, что отношение M / D автоматически добавляет подробные записи по мере необходимости, а также устанавливает первичные ключи таблицы подробностей.

Это также может быть причиной ошибки дублированного первичного ключа. Запись уже создается M / D-отношением, когда вы пытаетесь добавить / вставить другую.

0 голосов
/ 21 июня 2009

Прежде всего, на мой взгляд, идея автоинкремента и установки идентификаторов путем столкновения кода. Четкий путь - это сгенерировать ключ самостоятельно в коде. Особенно в многопользовательских приложениях, требующих вставки мастера / детали, трудно или невозможно получить правильный ключ для детализации.

Так что сгенерируйте идентификатор по коду. При разработке таблицы установите для поля идентификатора первичный ключ, но без автоматического приращения. Если я не ошибаюсь, для операции используется «Приложение».

Также, кажется, вы выполняете итерацию, пока включены визуальные элементы управления? (Item.Acactive). Но операция по своей природе является периодическим процессом. Для производительности графического интерфейса вы должны рассмотреть возможность отключения подключенных элементов управления БД, а затем выполнить операцию. Находясь в области мастер / детализация, это может быть проблемой, из-за которой два других курсора не выполняют итерацию должным образом.

...