0

我正在尝试将一行插入到引用其他表中的键的表中。在某些情况下,插入/选择将失败,因为所选值不能为空。我想知道哪些选择失败,以便我可以根据需要在其他表中创建必要的行。

下面的例子有点做作,但应该说明这里的挑战:

CREATE TABLE TableOne
(
  TableOneId INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Value VARCHAR(64) NOT NULL
) ENGINE=InnoDB;

CREATE TABLE TableTwo
(
  TableTwoId INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Value VARCHAR(64) NOT NULL
) ENGINE=InnoDB;

CREATE TABLE DependentTable
(
  DependentId INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  TableOneId INT UNSIGNED NOT NULL,
  TableTwoId INT UNSIGNED NOT NULL,
  Value FLOAT NOT NULL,
  FOREIGN KEY (TableOneId) REFERENCES TableOne(TableOneId),
  FOREIGN KEY (TableTwoId) REFERENCES TableOne(TableTwoId)
) ENGINE=InnoDB;

INSERT INTO DependentTable (Value, TableOneId, TableTwoId) SELECT 1.0, TableOne.TableOneId, TableTwo.TableTwoId FROM TableOne,TableTwo WHERE TableOne.Value='TableOneValue' AND TableTwo.Value='TableTwoValue';

Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

如果 'TableOneValue' 或 'TableTwoValue' 不存在,则 select 将返回 null 并插入 0 行 - 正如预期的那样。但是,我希望获得一些其他信息,这些信息可以让我确定哪个值不存在,以便我可以创建它。

问题是,至少在我的实际情况下,盲目地创建每个值来满足外键引用将是过度杀伤/昂贵的,因为有多个外键并且其中一些依赖表将具有其他必需的依赖关系。我想更智能地处理它并确定哪些引用不存在,而只创建那些引用。

我可以尝试在依赖表中一个接一个地创建行,等到实际插入一行(而不是获取重复条目),然后再次尝试原始插入 - 但感觉应该有更好/更多优雅的方式来做到这一点......

提前感谢您的任何建议/想法...

4

1 回答 1

0

我要做的是将所有内容插入没有外键的中间表中。然后使用该表查询TableOne和TableTwo,查看TableOneId和TableTwoId中的哪些项在TableOne和TableTwo中不存在。然后进行调整、清理等。

INSERT INTO IntermediateTable(DependentId, TableOneId, TableTwoId, Value) blah blah blah

下面将向您显示缺失值(对 TableTwo 重复):

SELECT * FROM IntermediateTable i LEFT JOIN TableOne t1 ON t1.TableOneid = i.TableOneId WHERE t1.TableOneId IS NULL

清理完成后,您可以将中间表中的所有内容复制到定义了外键的 DependentTable 中。

INSERT INTO DependentTable SELECT * FROM IntermediateTable-- 一切都已清理,因此现在 TableOne 和 TableTwo 中没有丢失的 id。

如果没有这个中间表,您将缺少一些可用于针对 TableOne 和 TableTwo 查询未定义 id 的东西。

于 2013-01-07T05:04:57.660 回答