`
13594135
  • 浏览: 190546 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

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


    由上可知,使用这种方式来更新表,需要用于更新的表(最终数据表)的关联字段必须设置为主键,且不可多字段主键。另外还有一个网友也指出了另外一个问题:
If the user has update permission on table A, but only has select permission on table B, they cannot update via the first example.  Oracle will return ORA-01031 (insufficient privileges).

    测试一下:

SQL> create user x identified by x;
SQL> grant create session on x;
SQL> grant select,update on a to x;
SQL> grant select on b to x;

SQL> create public synonym a for wangxiaoqi.a;
SQL> create public synonym b for wangxiaoqi.b;

SQL> conn x/x
Connected.
SQL> update ( select a1, b1 from a, b where a.id = b.id )
  2  set a1 = b1;
update ( select a1, b1 from a, b where a.id = b.id )
                               *
ERROR at line 1:
ORA-01031: insufficient privileges

--系统报错权限不够

SQL> update a set a1 = (select b1 from b where b.id=a.id);

2 rows updated.

--使用Update...Select...语句是可以更新成功的


--三、===========================
ORA-01779问题的解决作者:coordinator  来源:博客园

昨天帮一个师弟看一个ORACLE触发器T的问题,这个触发器建在视图V上,当用户往视图里插记录的时候就自动插到视图的组成表里。但是每次插入总提示,ORA-01779 cannot modify a column which maps to a non key-preserved table。而怪异的是,有一个视图V2和V的构成方式一摸一样,但是它的触发器T2就没问题。在网上找了很多帖子,绝大部分原因都是插入的基本表记录不唯一,我检查了触发器内容和基本表的keys,都没问题。

到第二天的时候突然看到一个帖子的原因解释:

view的更改是有限制的

General Rule
Any INSERT, UPDATE, or DELETE operation on a join view can modify only one underlying base table at a time.

UPDATE Rule
All updatable columns of a join view must map to columns of a key-preserved table. If the view is defined with the WITH CHECK OPTION clause, then all join columns and all columns of repeated tables are non-updatable.

DELETE Rule
Rows from a join view can be deleted as long as there is exactly one key-preserved table in the join. If the view is defined with the WITH CHECK OPTION clause and the key preserved table is repeated, then the rows cannot be deleted from the view.

INSERT Rule
An INSERT statement must not explicitly or implicitly refer to the columns of a non-key preserved table. If the join view is defined with the WITH CHECK OPTION clause, INSERT statements are not permitted.

(http://www.itpub.net/225291.html)

再检查了触发器,发现事件那块只关联了UPDATE,其他都没关联,粗心啊。全部关联上就好了。

看来触发器的几个选项一定要好好检查啊。



分享到:
评论

相关推荐

    Oracle两张表关联批量更新其中一张表的数据

    方法一(推荐): UPDATE 表2 ...尤其注意最后的外层where条件尤为重要,是锁定其批量更新数据的范围。 方法二: MERGE INTO 表2 USING 表1 ON (表2.A = 表1.A) -- 条件是 A 相同 WHEN MATCHED THEN UP

    ORACLE批量更新四种方法.txt ORACLE批量更新四种方法.txt

    ORACLE批量更新四种方法.txt ORACLE批量更新四种方法.txtORACLE批量更新四种方法.txt ORACLE批量更新四种方法.txt

    Oracle数据库分区表操作方法

    Oracle数据库分区表操作方法Oracle数据库分区表操作方法

    Oracle数据表更新即时通告的实现方法.pdf

    Oracle数据表更新即时通告的实现方法.pdf

    Oracle批量更新方法.pdf

    Oracle批量快速更新方法

    Oracle表删除大量数据(千万)后查询变慢问题(原因分析)

    Oracle 表删除大量数据后查询变慢问题分析 在 Oracle 数据库中,如果删除了大量数据(千万级别),可能会出现查询变慢的问题。下面我们将分析这个问题的原因,并提供解决方案。 问题的原因主要有两个方面: 1. 表...

    oracle中对blob字段的处理方法

    oracle中对blob字段的处理方法,包括增加,删除,修改,更新等操作。

    Oracle中用一张表的字段更新另一张表的字段

     SQL Server中这是比较容易解决的,而Oracle中不知道方法了。  SQL Server中类似问题的解决方法  后来只好用笨的方法:  首先,将数据复制到Excel;(假设称测试库的表为A–含有数据)  然后,在开发库中...

    更改Oracle表中字段的顺序的终极方法

    想要调整字段顺序非常不容易,网上的方法竟然都是备份表之后删除再重建,这样整的话不是麻烦而是忒麻烦。查找了一些资料,发现有办法可以解决,而不用那么大费周章,如果更改的话需要SYS的权限,废话少说了

    oracle注入utl_http方法.doc

    Oracle 注入 utl_http 方法 Oracle 注入 utl_http 方法是指攻击者使用...4. 更新补丁:及时更新补丁,可以修复 Oracle 数据库中的缺陷。 UTL_HTTP 方法是一种危险的攻击方法,需要采取有效的防御措施来保护系统安全。

    Oracle 12.2主从数据同步方法

    内容涉及oracle 12的容器数据库,可插入数据库,目前只做了DML的数据同步(不含ddl的同步)

    sql_server连接Oracle方法(最全)

    "SQL Server 连接 Oracle 方法" SQL Server 连接 Oracle 方法是数据库管理系统中的一个重要话题。本文将详细介绍如何在 SQL Server 中连接 Oracle 数据库,并解决在连接过程中可能出现的问题。 安装 Oracle 客户端...

    oracle执行update语句时卡住问题分析及解决办法

    原因和解决方法 这种只有update无法执行其他语句可以执行的其实是因为记录锁导致的,在oracle中,执行了update或者insert语句后,都会要求commit,如果不commit却强制关闭连接,oracle就会将这条提交的记录锁住。...

    Oracle游标使用方法及语法大全

    Oracle 游标使用方法及语法大全 Oracle 游标是 PL/SQL 程序中的一种重要组件,用于处理查询结果集。游标可以分为隐式游标和显式游标两种,隐式游标由 PL/SQL 管理,隐式游标打开时查询开始,查询结束时隐式游标自动...

    ORACLE查询表最近更改数据的方法

    修改项目时,涉及到了Oracle中许多表的修改(包括:增加、删除字段,修改注释等)。由于开始没有进行记录,造成在上测试机时,忘记了具体修改过哪些表了。后来在网上查找了一些资料,例如: 代码如下: 1、select uat...

    Oracle多表级联更新详解

    我们在平时的工作中可能遇到过,多表级联更新,我也在网上看到过不少的方法,但是使用这些方法一般都没成功过,所以今天我给大家介绍一种稍微麻烦的方法,有需要的朋友可以参考下

    sap 与 oracle数据库的连接

    sap开发中 模块连接oracle数据库的具体方法步骤详细说明

    基于JDBC同步Oracle到MySQL

    分别有:数据源配置、数据表结构转换、字段更新、数据迁移、根据oracle SQL的UPDATE DELETE 事物执行记录转为Mysql可执行SQL,同步执行到MySql数据库,此项目为个人兴趣爱好练手项目,项目问题欢迎留言,共同进步...

    导入excel,txt文件到oracle数据库

    ImportExcel2Oracle.aspx通过dateset.update把数据更新到oracle数据库中的RAWDATA表中,当oracle数据库表中数据很大时,这种导入速度很慢,但是表数据空时导入比较快。ImportExcelData2Oracle.aspx通过oracle 的sql...

Global site tag (gtag.js) - Google Analytics