日期:2014-05-16  浏览次数:20436 次

oralce多表更新方法
--备份
create table content_20110112 as select * from content;

alter table content_20110112 add constraint content_20110112_key primary key(contid);

--回退
update content  t
set t.products = (select o.products from content_20110112 o where o.contid = t.contid)
where t.object_id in('11111111000000010000000000000896');

--回退方法二

update (
select /*+ BYPASS_UJVC */ t.contid t1,o.contid t2,t.products as p1 , o.products as p2
from content_20110112 o join content t on t.contid = o.contid
--where t.object_id in('11111111000000010000000000000896')
) xx
set  p1 = p2 

BYPASS_UJVC的作用是跳过Oracle的键检查。



引用
Oracle中Update的一个写法,注意异常ORA-01779
---------------------------

这篇是转的,大家在写SQL的时候特别注意不要犯此类ORA-01779错误.

-- 一、==========
Oracle中试图对一个子查询进行更新时可能会出现ORA-01779错误。该错误的内容为:

ORA-01779: cannot modify a column which maps to a non-key-preserved table例如,使用以下的更新查询就会出现该错误。

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);
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; ORA-01779: cannot modify a column which maps to a non-key-preserved table
这个错误的意思是,子查询的结果中,更新数据源(test2)的内容不唯一,导致被更新对象(test1)中的一行可能对应数据源(test2)中的多行。本例中,test2表的id不唯一,因此test2表中可能存在id相同但是num不相同的数据,这种数据是无法用来更新 test1 的。

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

CREATE UNIQUE INDEX test2_idx_001 ON test2 (id);
之后上面的更新就可以执行了。

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

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;
BYPASS_UJVC的作用是跳过Oracle的键检查。这样虽然能够执行了,但是如果test2中存在不唯一的数据,test1就会被更新多次而导致意想不到的结果。

--二、========================

SQL> create table a ( id int, a1 varchar2(25) );
SQL> create table b ( id int, b1 varchar2(25) );
SQL> insert into a values ( 1, 'Hello' );
SQL> insert into a values ( 2, '**xx' );
SQL> insert into b values ( 2, 'World' );
SQL> commit;


SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set a1 = b1;
set a1 = b1
    *
ERROR at line 2:
ORA-01779: cannot modify a column which maps to a non key-preserved table

--无法Update,必须要有一个主键

SQL> alter table b add constraint b_key primary key(id);
SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set a1 = b1;

1 row updated.

--可以Update


SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set b1 = a1;
set b1 = a1
    *
ERROR at line 2:
ORA-01779: cannot modify a column which maps to a non key-preserved table

--交换位置后依旧无法更新

SQL> alter table b drop constraint b_key;
SQL> alter table a add constraint a_key primary key(id);
SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set b1 = a1;

1 row updated.

--为表a设置主键后可以更新

SQL> alter table a drop constraint a_key;
SQL> alter table a add constraint a_key primary key(id,a1);
SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set b1 = a1;
set b1 = a1
    *
ERROR at line 2:
ORA-01779: cannot modify a column which maps to a non key-preserved table

--使用联合主键仪不可以的,必须是关