【问题标题】:multi-table insert using sequence-generated id fails due to foreign key violation由于外键违规,使用序列生成的 id 进行多表插入失败
【发布时间】:2016-05-04 10:46:22
【问题描述】:

我想在两个表中使用相同的序列生成值将显式数据批量插入到由外键链接的两个不同表中。

我正在尝试使用 INSERT ALL 指令和由连续 UNION ALL 语句组成的 WITH 子句来实现这一点。

只要 with 子句返回不超过 256 行,一切正常。一旦我添加另一个 UNION ALL 条目,我就会收到以下错误:

ORA-02291: 违反完整性约束 (MY_SCHEMA.FK_TABLE_B_TO_TABLE_A) - 未找到父键 *原因:外键值没有匹配的主键值。 *操作:删除外键或添加匹配的主键。

如果我禁用外键约束,那么一切正常(即使超过 256 行)。

我的指令是这样的:

insert all 
  into MY_SCHEMA.TABLE_A (ID, COLUMN_1, COLUMN_2)
    values (MY_SCHEMA.MY_SEQUENCE.nextval, COLUMN_1, COLUMN_2)
  into MY_SCHEMA.TABLE_B (ID, COLUMN_3) 
    values (MY_SCHEMA.MY_SEQUENCE.nextval, COLUMN_3) 

  with input_data as (
    select 11 COLUMN_1, 12 COLUMN_2, 13 COLUMN_3
      UNION ALL
    select 21 COLUMN_1, 22 COLUMN_2, 23 COLUMN_3
      UNION ALL
      ...
      UNION ALL
    select 31 COLUMN_1, 32 COLUMN_2, 33 COLUMN_3

  )
  select * from input_data;

这种指令可以处理的数据量是否有一些限制?还是我错过了什么?

我正在使用 Oracle 11g 和 SQLDeveloper。

【问题讨论】:

  • 你错过了一些东西。该错误是数据验证错误,表示未满足外键条件。它与数据的大小无关。一个可能的罪魁祸首是您要插入的其他行具有重复值。
  • 感谢您的意见,那么您如何解释禁用 FK 会使错误消失(我应该提到的所有数据都已正确插入)?
  • 那么当你禁用 FK 并使用相同的 union all 时,所有(超过 256 个)行都被插入并且表具有相同的 ID?
  • 正确。会不会是插入顺序不确定?

标签: sql oracle sql-insert bulkinsert multi-table


【解决方案1】:

当使用多表插入时,最好禁用甚至删除所有约束。它有一些重要的限制:

  • 不应使用序列
  • 不保证插入表的顺序

因此,即使您插入完全有效的数据,它也可能会因 FK 约束而失败。 无论如何,如果您想快速批量插入数据,您不想浪费时间等待 FK 被检查。

更新:可能重复:https://dba.stackexchange.com/questions/23384/using-multi-table-insert-for-parent-and-child-table

Oracle 错误 (2891576) 尚未修复。 Oracle 提供解决方法:

解决方案(文档 ID 265826.1)

"Oracle插入数据的表顺序不 确定(保证)。因此,在发出多表之前 insert 语句,您应该推迟任何约束并禁用任何 取决于多表的特定表顺序的触发器 插入操作。”

解决方法:

  1. 在运行此类多路径插入时禁用外键。
  2. 使用 DEFERRED CONSTRAINTS,以便仅在提交时签出。

关于延迟约束检查 Metalink Note:73647.1 "Deferred 约束示例"

【讨论】:

  • 你说的 sequences cannot be used 是什么意思?我知道它们不能在子查询中使用(请参阅Oracle official documentation),但在我的示例中,我使用序列,它是一个多表插入...
  • 我在Official documentation 中也找不到任何关于未定义INTO 子句的执行顺序的信息
  • 我认为这些限制是我在数据仓库指南的某处读到的。以下是提到的其他一些限制:allthingsoracle.com/multi-table-insert-statements-in-oracle
  • 感谢您上次的编辑,这正是我想要的!
  • @David Balažic 尚未修复。 (甚至在 12r2 中也没有)
猜你喜欢
  • 2017-08-27
  • 2015-04-20
  • 2014-05-13
  • 1970-01-01
  • 2011-11-28
  • 2014-03-19
  • 1970-01-01
  • 1970-01-01
  • 2020-02-26
相关资源
最近更新 更多