一、如果两张表有主键关系的话:
UPDATE (SELECT tt1.col1 ,tt2.cola,tt1.id,tt2.id FROM tt1,tt2 WHERE tt1.ID=tt2.ID)
SET col1=cola;
报错:ORA-01779: 无法修改与非键值保存表对应的列
根据错误提示:”无法修改与非键值保存表对应的列”,初步推断为tt2中没有主键?
那么在tt2上添加主键后再更新试试
ALTER TABLE tt2 ADD CONSTRAINT pk_tt2_id PRIMARY KEY(ID);
UPDATE (SELECT tt1.col1 ,tt2.cola,tt1.id,tt2.id FROM tt1,tt2 WHERE tt1.ID=tt2.ID)
SET col1=cola;
发现可以成功更新数据。
然后将在tt2上加的主键删除,再在tt1上添加主键试试,
ALTER TABLE tt2 DROP CONSTRAINT pk_tt2_id;
ALTER TABLE tt1 ADD CONSTRAINT pk_tt1_id PRIMARY KEY(ID);
再执行第3 步中的更新语句,发现还是报错:ORA-01779: 无法修改与非键值保存表对应的列
用A表去更新B表的数据,A表的关联条件必须为主键,Oracle这样做的目的是保证表A的满足关联条件的数据是唯一的,
这样在更新B表数据时才有意义(自己都不确定怎么影响别人,是吧,hehe),
当然,如果两表关联的字段都为主键,则无论谁更新谁都没有问题。
结论:用A表数据更新B表数据,则A与B的对应关系为:1:1 或 1:n。
二、如果两站表无任何关系
1.新建临时表
临时表数据来源为b表,给a表更新
数据结构有最少有主键id,和要更新的列
drop table temp_tt2;
create GLOBAL TEMPORARY table tt2(
id number(10),
col1_b varchar2(10)
) ON COMMIT PRESERVE ROWS;
2.不要忘了设置主键
alter table temp_tt2 add constraint pk_id_l primary key (id)
3.从tt2中插入数据到temp_tt2
insert into temp_tt2
select id,col1 from tt2
4.用临时表和a表关联进行批量更新
UPDATE (SELECT tt1.col1 ,temp_tt2 .col1_b,tt1.id,temp_tt2 .id FROM tt1,temp_tt2 WHERE tt1.ID=temp_tt2 .ID)
SET col1=col1_b;
用A表去更新B表的数据,A表的关联条件必须为主键,Oracle这样做的目的是保证表A的满足关联条件的数据是唯一的,再执行第3 步中的更新语句,发现还是报错:ORA-01779: 无法修改与非键值保存表对应的列。根据错误提示:”无法修改与非键值保存表对应的列”,初步推断为tt2中没有主键?这样在更新B表数据时才有意义(自己都不确定怎么影响别人,是吧,hehe),结论:用A表数据更新B表数据,则A与B的对应关系为:1:1 或 1:n。4.用临时表和a表关联进行批量更新。临时表数据来源为b表,给a表更新。
上周在做视图更新的时候,报了一个错:ORA-01779: 无法修改与非键值保存表对应的列。
官方文档是这么解释的:ORA-01779cannot modify a column which maps to a non key-preserved table
解决这个问题的关键在于搞清楚什么是Key-Preserved Tables?
上面是官方文档的解释。大致意思:搞清楚key-pr...
#4 目的是为了表连接只能匹配出一条数据,通过关联条件实现一对一关系,即表A 表B表连接,通过关联条件,A表的一条记录只能匹配出B表的一条数据。类似于scott.emp.deptno=scott.dept.deptno
必修红框内字段有唯一约束 unique或者PK
必须每个关联表都要有where条件,且n个表要有n-1个表连接条件
待更新的主表可以没有主键,唯一性约束等
set语句待修改的字段只能是主表字段,也就是等号前面的字段必须是主表的字段,否则ora-01776
当数据表(非目标表)是联合主键时
今天遇到一个错误:
ORA-
01779:
无法修改与非键值保存表对应的
列。
后来发现,当要对一个基于多
表连接的视图进行插入,更新等操作时,容易出现这个错误。
解决办法:个人认为,这个视图不能操作,可以对它基于的
表进行操作,这样,该视图里也就有相应数据了。
于是,做了下面这个实验。
SQL> create table emp2 as select * from emp;
表已创建。