【问题标题】:Create table as Select, then Update statement with JOIN in Oracle将表创建为 Select,然后在 Oracle 中使用 JOIN 更新语句
【发布时间】:2019-11-03 16:30:36
【问题描述】:

我正在使用 Oracle HR 数据库。 我想知道为什么以下查询不起作用:

create table ecopy 
as select *
from employees;

create table dcopy
as select *
from departments;

UPDATE (select d.location_id, e.salary 
from ecopy e inner join dcopy d 
on e.department_id=d.department_id)
set salary = salary+1 
where location_id = 1800

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

虽然这个,在原始表上正在做它的工作:

UPDATE (select d.location_id, e.salary 
from employees e inner join departments d 
on e.department_id=d.department_id)
set salary = salary+1 
where location_id = 1800

谁能给我解释一下?

【问题讨论】:

  • 可能是因为create table as缺少主键约束和唯一键约束等约束。
  • 我也这么认为,但我没想到在值正常的情况下会如此需要
  • 如果你也这么想,你可以尝试一个实验:在你的 copy 表上,在dcopy.department_id 上添加主键约束并尝试update 语句再次。您会看到它会按预期进行。 (实际上,该列上的唯一约束或唯一索引就足够了;显然“主键”更强大,所以这也足够了。)然后你问了一个非常合理的问题,“为什么”?答案是你看到的错误是一个编译错误——它不是在运行时抛出的,而是在更早的时候抛出的。
  • 发生的情况是,在解析 update 语句的过程中,解析器检查现有约束 - 它确实检查实际数据以查看没有重复(即使没有唯一约束)。在编译时,在查看数据之前,Oracle 要么知道该列是唯一的,要么不知道。如果没有约束或索引,则不会,因此会出现编译时错误。

标签: sql oracle


【解决方案1】:

解释如下:

在您的现实生活中,您的关系由键支持 - 引用约束

employee.department_id(MANY) = departments.department_id(ONE)

UPDATEJOIN 的情况下,您只能更新“MANY”表中的列并且只有当它们具有真实引用时。

您的 Create as select. . . 表肯定没有这些引用,因此 Oracle 优化器会抛出此错误。

这里有一些参考 Reference 1 Reference 2

【讨论】:

    猜你喜欢
    • 2020-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多