Oracle 多表关联更新


drop table course;
create table course (
id integer,
teacherNo integer,
teacherDesc varchar2(100),
teacherName varchar2(50),
courseName varchar2(50)
);
insert into course values(1,100,'Mr.zhang','ZhangSan','English');
insert into course values(2,101,'Mr.wang','WangWu','History');
insert into course values(2,101,'Mr.wang','WangWu','Chinese');

update course set teacherDesc='Good Teacher' where teacherNo=101;
commit;
drop table teacher;
create table teacher(
id integer,
teacherDesc varchar2(100),
teacherName varchar2(50)
);
insert into teacher values(100,'Mr.zhang','ZhangSan');
insert into teacher values(101,'Mr.wang','WangWu');
update teacher set teacherDesc='Excellent Teacher' where id=101;
commit;
select c.teacherdesc, c.teachername, t.teacherdesc, t.teachername
  from course c, teacher t
 where c.teacherno = t.id
   and (c.teacherdesc != t.teacherdesc or c.teachername != t.teachername);

update course c
   set (c.teacherdesc, c.teachername) =
       (select t.teacherdesc, t.teachername
          from teacher t
         where c.teacherno = t.id
           and (c.teacherdesc != t.teacherdesc or
               c.teachername != t.teachername))
 where exists (select 1
          from teacher t
         where c.teacherno = t.id
           and (c.teacherdesc != t.teacherdesc or
               c.teachername != t.teachername));
commit;
select c.teacherdesc, c.teachername, t.teacherdesc, t.teachername
  from course c, teacher t
 where c.teacherno = t.id
   and (c.teacherdesc != t.teacherdesc or c.teachername != t.teachername);

select c.teacherdesc, c.teachername, t.teacherdesc, t.teachername
  from course c, teacher t
 where c.teacherno = t.id;

   

 


update时报ORA-01779:
数据准备:

CREATE TABLE test1 ( id integer primary key, num integer );
INSERT INTO test1 VALUES (1,0);
INSERT INTO test1 VALUES (2,0);
INSERT INTO test1 VALUES (3,0);
INSERT INTO test1 VALUES (4,0);  

CREATE TABLE test2 ( id integer, num integer, upd integer );
INSERT INTO test2 VALUES (1,10, 0);
INSERT INTO test2 VALUES (2,20, 1); 

commit;

执行如下更新语句会报错:ORA-01779: 无法修改与非键值保存表对应的列
01779, 00000, "cannot modify a column which maps to a non key-preserved table"
// *Cause: An attempt was made to insert or update columns of a join view which
//        map to a non-key-preserved table.
// *Action: Modify the underlying base tables directly.

UPDATE (SELECT T1.ID ID1, T1.NUM NUM1, T2.ID ID2, T2.NUM NUM2
          FROM TEST1 T1, TEST2 T2
         WHERE T1.ID = T2.ID
           AND T2.UPD = 1)
   SET NUM1 = NUM2;

这个错误的意思是,子查询的结果中,更新数据源(test2)的内容不唯一,导致被更新对象(test1)中的一行可能对应数据源(test2)中的多行。
本例中,test2表的id不唯一,因此test2表中可能存在id相同但是num不相同的数据,这种数据是无法用来更新 test1 的。【这个报错属于事前检查,没有通过校验】

解决方法就是保证数据源的唯一性,例如本例中可以为test2.id创建一个唯一索引:

CREATE UNIQUE INDEX test2_idx_001 ON test2 (id);

之后上面的更新就可以执行了。
也可以使用如下命令来使用test2中记录具有唯一性

alter table test2 modify id unique;

另外也可以强制 Oracle 执行,方法是加上 BYPASS_UJVC 注释。

UPDATE (SELECT /*+ BYPASS_UJVC */
         T1.ID ID1, T1.NUM NUM1, T2.ID ID2, T2.NUM NUM2
          FROM TEST1 T1, TEST2 T2
         WHERE T1.ID = T2.ID
           AND T2.UPD = 1)
   SET NUM1 = NUM2;

BYPASS_UJVC的作用是跳过Oracle的键检查。
这样虽然能够执行了,但是如果test2中存在不唯一的数据,test1就会被更新多次而导致意想不到的结果。【有风险,不建议使用】  

http://www.linuxidc.com/Linux/2012-08/69089.htm

 

时间: 2024-07-30 12:24:26

Oracle 多表关联更新的相关文章

Oracle\MS SQL Server Update多表关联更新

原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.我们先来讨论根据其他表数据更新你要更新的表   一.MS    SQL    Server   多表关联更新      sql server提供了update的from 子句,可以将要更新的表与其它的数据源连接起来.虽然只能对一个表进行更新,但是通过将要更新的表与其它的数据源连接起来,就

Oracle多表关联的update和delete

由于Oracle不支持update或delete from语句,因此,Oracle的多表关联update和delete必须借助于 子查询,同理,Oracle也不支持同时update或delete多张表,其典型用法如下: 多表关联update 首先,构造测试表和数据如下: SYS@TEST16> create table testa as select owner,table_name,status from dba_tables; Table created. SYS@TEST16> crea

SQL update 多表关联更新的实现代码

实现多表更新,尤其是A表和A的子表B表数据更新,下面是例子 有A.B张表,其记录如下: A表 c1       c2 -------------- 1       a1 2       a2 3       a3 8       a8 B表 c1       c3 -------------- 1        b1 2        b1 3        b3 10      b10 A.c1与B.c1相等,用一条sql语句,实现A.c2的值更新为B.c3 -----------------

mysql 多表关联更新/删除sql语句

1.mysql 多表关联delete中使用别名,tblwenhq是真实的表名,a是tblwenhq的别名,b是另一个表名  代码如下 复制代码 DELETE  a FROM tblwenhq a,b where a.id=b.id 2.使用mysql进行delete from操作时,若子查询的 FROM 字句和更新/删除对象使用同一张表,会出现错误. DELETE FROM tab1 WHERE col1 = ( SELECT MAX( col1 ) FROM tab1 ); ERROR 109

Oracle多表级联更新详解

我们在平时的工作中可能遇到过,多表级联更新,我也在网上看到过不少的方法,但是使用这些方法一般都没成功过,所以今天我给大家介绍一种稍微麻烦的方法,有需要的朋友可以参考下   用游标实现,我觉得绝对这种方法比较安全的.--首先定一个游标把需要用到的一些数据存放到游标中: 复制代码 代码如下: declare   CURSOR D_CURSOR_CUS_INFO IS     select t3.id_           as id_,            t3.owe_money_    as

Oracle多表级联更新详解_oracle

用游标实现,我觉得绝对这种方法比较安全的.--首先定一个游标把需要用到的一些数据存放到游标中: 复制代码 代码如下: declare   CURSOR D_CURSOR_CUS_INFO IS    select t3.id_           as id_,           t3.owe_money_    as owe_money_,           a.heatingArea    as heating_area_    from T_CUS_OWE_MONEY_2 t2   

ORACLE中如何批量更新关联表

在SQL SERVER中,关联表的批量更新,可以参看这里: http://www.cnblogs.com/downmoon/archive/2007/12/29/1019832.html Oracle下没找到好的语法,临时用这个: update employee set hrdeptname= (select d.DEPTNAME from DEPARTMENT d where ROWNUM=1 and d.deptID=employee.hrdeptID ) 对应的SQL Server语法:

使用外部表关联MySQL数据到Oracle

因为业务需要,有个临时的活动需要DBA来支持一些数据业务,问题来了,需要从MySQL端同步一部分数据到Oracle端,然后从Oracle端匹配查到相应的数据返回给MySQL,至于原因,也是不同的业务系统,不同的权限分配,还没法做到一个应用端去读取这些信息,而且也有安全的考虑,大体就是两部分的数据也是互相补充,但又彼此独立,是一个全集和子集的关系. 这个流程本来从开发的角度来看似乎是一头雾水,所以交给他们来规划就容易出现问题,最后沟通后的流程是下面的形式. 下面这个图左边是Oracle的环境,右边

oracle 两表递归关联查询

问题描述 oracle 两表递归关联查询 哪位大神帮忙指点下,现表A有字段a,b,c 表B有字段d 然后用表A和表B关联,先使用表B的字段d和表A的字段c关联如果关联不上,再用表B的字段d和表A的字段b关联,如果关联不上在用表B的d字段和表A的字段a进行关联,其中表A的字段c从属字段b,字段b从属字段a 解决方案 Oracle创建两表关联查询的视图查询oracle约束所关联的表查询oracle约束所关联的表 解决方案二: 有点像地市层级.但数据库不会这样设计把. 直接 用or将3种关联 联系起来