SQL 错误:ORA-01779:无法修改映射到非键保留表的列

Posted

技术标签:

【中文标题】SQL 错误:ORA-01779:无法修改映射到非键保留表的列【英文标题】:SQL Error: ORA-01779: cannot modify a column which maps to a non key-preserved table 【发布时间】:2014-01-17 14:02:05 【问题描述】:

我正在尝试使用另一个表中的数据更新一个表。 数据是为了保持简单而编造出来的

项目(表格)

ID   FK_INCIDENT-ID  DAYS
---------------------------
01   10              0
02   20              0

事件(表格)

ID  FK_PRIORITY-ID
------------------
10  100
20  200

优先级(表格)

ID   DAYS
---------
100  1
200  2

我需要做的是将 DAYS 从 PRIORITY 复制到 DAYS in PROJECT 并 INCIDENT 将它们绑定在一起。

更新到 PROJECT 表后应该是这样的

ID   FK_INCIDENT-ID   DAYS
---------------------------
01   10               1
02   20               2

PROJECT 与 PRIORITY 的唯一联系是通过 INCIDENT。

FK_INCIDENT-ID(在 PROJECT 中)到 FK_PRIORITY-ID(在 INCIDENT 中)到 ID(在 PRIORITY 中)

update (select i.ID, pro.Days, pri.Days AS Days2
from incident i
left join project pro on (i.id = pro.FK_Incident-id)
left join priority pri on (i.Fk_priority-id = pri.id)
where pro.days = 0) t
set t.Days = t.Days2

感谢您提供的任何帮助。

【问题讨论】:

【参考方案1】:

在我看来,您查询中的第一个联接无效:我认为,您应该将 (i.FK_Incident-id = pro.id) 替换为 (i.id = pro.FK_INCIDENT-ID)。

另外,here is nice explanation on the topic of key-preserved tables

【讨论】:

【参考方案2】:

对于您所描述的关系,您似乎以错误的顺序加入您的表格;你说:

FK_INCIDENT-ID(在 PROJECT 中)到 FK_PRIORITY-ID(在 INCIDENT 中)到 ID(在 PRIORITY 中)

但您要加入 INCIDENTPROJECTPRIORITY

这就是您收到错误的原因。您的架构中没有任何内容阻止事件映射到多个项目,左外连接意味着即使没有出现相同的事件也可以出现多次,如果它只出现一次,那么您不一定知道如何回到正确的记录进行更新。

如果您重新排序内联视图查询以将 PROJECT 连接到 INCIDENTPRIORITY,那么它可以工作(使用有效名称):

update (
  select i.ID, pro.Days, pri.Days AS Days2
  from project pro
  left join incident i on (i.id = pro.incident_id)
  left join priority pri on (pri.id = i.priority_id)
  where pro.days = 0) t
set t.Days = t.Days2;

SQL Fiddle

为什么days 值被非规范化到project 表中呢?或者它是否意味着其他的东西(比如实际的解决时间,而不是优先级的目标),你只是假设没有设置它的项目是最坏的?虽然这似乎更适合incident 级别,但我会想到。当然,或者这一切都可以编造出来……

【讨论】:

以上是关于SQL 错误:ORA-01779:无法修改映射到非键保留表的列的主要内容,如果未能解决你的问题,请参考以下文章

Oracle - 更新连接 - 非键保留表

Oracle - 更新连接 - 非键保留表

RestKit 映射错误“无法将对象集合映射到非可变集合。”

更新表不能修改映射到非键保留表的列

如何使用 Hibernate 将 SQL 查询的结果最好地映射到非实体 Java 对象?

如何解决映射到非java文件类型文本的java文件