Как назначить внешний ключ в отношении основной детали, используя генератор в Delphi XE2?
В качестве примера:
У меня есть две таблицы в Firebird:
TB_CUSTOMER
- IDCUSTOMER (автоинкрементный генератор)
- ИМЯ ПОКУПАТЕЛЯ
TB_PHONE
- IDPHONE
- IDCUSTOMER (первичный ключ от TB_CUSTOMER)
- ТЕЛЕФОН
У меня есть регистрационная форма, разработанная в Delphi. Данные таблицы TB_PHONE обрабатываются с использованием dbgrid. Я не могу присвоить значение полю IDCUSTOMER в TB_PHONE, потому что оно не было сгенерировано генератором Firebird. Как я могу сделать отношения между таблицами? Я хочу реализовать это без предварительного сохранения данных таблицы TB_CUSTOMER. Я использую модули данных с IBDAC.
Любой Sugest?
2 ответа
Перед тем, как детальная таблица может быть вставлена в, вы должны обновить PK-index над мастер-таблицей и иметь в ней правильный master-ID. Это означает, что некоторый фрагмент кода должен вставить основную запись перед вставкой подробной записи. Где этот кусок кода будет - ограничен только вашей фантазией. Несколько договоренностей включают
вставьте мастер-строку в ваше приложение. Прочитайте идентификатор строки. Вставьте строку подробностей, используя этот идентификатор.
прочитать идентификатор из этого генератора, затем вставить обе строки (мастер 1-й), используя полученный идентификатор
создать
stored procedure
вставка обеих строк и возвращение идентификатора (реализация на стороне сервера №1 или №2)использование
EXECUTE BLOCK
в основном специальная анонимная процедура SQL. Но это доступно только в FB 2.x и, если не использовать пространство имен, оно уступает #3.добавлять
BEFORE INSERT
вызвать на таблицу подробностей, поиск идентификатора в мастере и добавление одного, если не найден. Это замедлит все операции вставки (даже если мастер-идентификатор уже существует - это нужно проверить), не сможет заполнить все остальные главные столбцы, кроме идентификатора, и потенциально опасно из-за сокрытия проблем логики приложения. Но все же это может быть реализовано (хотя уродливый и грязный метод)создать master-join-detail
VIEW
и добавитьINSERT
триггер для него, распространяющий новую строку представления в мастер-таблицу и таблицу подробностей.
и так далее
Я хочу реализовать это без предварительного сохранения данных таблицы TB_CUSTOMER
Там твоя проблема. Вам нужен первичный ключ из главной таблицы, прежде чем вы сможете сохранить детали. Вот как это работает. Но если вам нужно убедиться, что значения сохранены вместе, вы можете сделать это как транзакцию. В Firebird вы можете сделать это так:
- Начните транзакцию. Как именно вы это сделаете, зависит от того, какую библиотеку БД вы используете для доступа к вашей базе данных Firebird.
- Запустите оператор INSERT INTO ... RETURNING, чтобы вставить строку в основную таблицу и извлечь сгенерированное значение как одну операцию.
- Используйте сгенерированное значение PK, чтобы заполнить значение FK в вашей подробной таблице.
- Вставьте строку подробностей.
- Зафиксируйте транзакцию.