【发布时间】: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 要么知道该列是唯一的,要么不知道。如果没有约束或索引,则不会,因此会出现编译时错误。