0

举个例子:

我在火鸟中有两张桌子:

TB_CUSTOMER

  • IDCUSTOMER(自动增量生成器)
  • 顾客姓名

TB_PHONE

  • 手机
  • IDCUSTOMER(来自 TB_CUSTOMER 的外键)
  • 电话

我有一个用 Delphi 开发的注册表单。表数据 TB_PHONE 使用 dbgrid 处理。我无法在 TB_PHONE 中分配字段 IDCUSTOMER 的值,因为它不是由 Firebird 生成器生成的。如何建立表之间的关系?我想在不先保存表数据 TB_CUSTOMER 的情况下实现它。我正在使用带有 IBDAC 的数据模块。

有什么建议吗?

4

2 回答 2

1

我想在不先保存表数据 TB_CUSTOMER 的情况下实现它

有你的问题。在保存详细信息之前,您需要主表中的主键。这就是它的工作方式。但是,如果您想要确保将值一起保存,您可以将其作为事务来执行。在 Firebird 中,您可以这样做:

  • 开始交易。具体操作方式取决于您用于访问 Firebird 数据库的数据库库。
  • 运行INSERT INTO ... RETURNING 语句将行插入到主表中,并将生成的值作为单个操作检索。
  • 使用生成的 PK 值在您的明细表中填写 FK 值。
  • 插入详细信息行。
  • 提交事务。
于 2013-06-18T16:38:41.497 回答
1

在可以插入明细表之前,您应该更新主表上的 PK-index 并在其中包含正确的主 ID。这意味着某些代码应该在插入详细记录之前插入主记录。这段代码的位置 - 仅受您的幻想限制。很少有安排包括

  1. 在您的应用程序中插入主行。读取行的 id。使用此 ID 插入详细信息行。

  2. 从生成器读取 ID,然后使用获得的 ID 插入两行(主第一行)

  3. 创建一个stored procedure,插入两行并返回 ID(实现 #1 或 #2 服务器端)

  4. 使用EXECUTE BLOCK- 基本上是临时匿名 SQL 过程。但这仅在 FB 2.x 中可用,除了不使用命名空间之外,它不如 #3。

  5. BEFORE INSERT触发器添加到明细表中,在 master 中搜索 ID,如果找不到则添加一个。这会减慢所有插入操作(即使主 ID 已经存在 - 应该检查),将无法填充除 ID 之外的所有其他主列,并且由于隐藏应用程序逻辑问题而存在潜在危险。但仍然可以实现(虽然丑陋和肮脏的方法)

  6. 创建 master-join-detailVIEW并为其添加INSERT触发器,将新的 view-row 传播到 master-table 和 details-table 中。

等等

于 2013-06-18T16:04:37.360 回答