update更新多行数据方式_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
2
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2399 | 回复: 1   主题: update更新多行数据方式        下一篇 
xiaoyang
注册用户
等级:上士
经验:253
发帖:75
精华:0
注册:2011-10-19
状态:离线
发送短消息息给xiaoyang 加好友    发送短消息息给xiaoyang 发消息
发表于: IP:您无权察看 2015-7-24 17:29:22 | [全部帖] [楼主帖] 楼主

1.单表更新

方案:使用标准update语法即可,执行稳定且效率较高

update table

set (column1,column2,...)=

value1,value2,...

;



2.多表关联更新

举例:更新gkfq_rec表中所有slid与oa2_ftask表fi_inst相同的行,blzt字段值=oa2_ftask表的ft_lstate。


create table gkfq_rec (
slid char(12) parimary key,
blzt varchar2(50),
wjbt varchar2(100) not null,
........
);
create table oa2_ftask (
fi_inst char(12) parimary key,
fi_state int not null,
ft_lstate int not null,
...
);


 方法描述



 适用范围



 运行效率



 传统方案                  一般情况适用  单表更新效率高且稳定,多表时效率较慢

 inline view更新法  关联字段为主键  速度较快

 merge更新法          关联字段非主键,适用于两表关联  非主键关联表更新,速度较快

 快速游标更新法  逻辑较复杂的情况  复杂逻辑时效率很高

(1)传统方案(速度可能最慢)

update gkfq_rec a 

set blzt=

(select b.ft_lstate from oa2_ftask b where a.slid=b.fi_inst)

where exists

(select 1 from oa2_ftask b where a.slid=b.fi_inst)

;



//子查询返回多行值时,通过where exists条件逐行过滤,一一匹配实现set唯一值



(2)inline view更新法(关联主键字段,速度较快)

方案:更新一个临时建立的视图。要求B表的主键字段必须在where条件中,并且是以=号来关联被更新表,否则可能报错:ORA-01779:无法修改与非键值保存表对应的列。当B表主键字段为多列组合时,也有可能出现这一报错。update (select a.blzt as blzt,b.ft_lstate as ft_lstate

from gkfq_rec a,oa2_ftask b where a.slid=b.fi_inst) 

set blzt=ft_lstate

;



(3)merge更新法(关联字段非主键时,速度较快)

语法:

MERGE INTO table_name alias 1

USING (table view sub_query) alias 2

ON (join condition)

WHEN MATCHED THEN

UPDATE 

SET col1=col_val1,

    col2=col_val2

WHEN NOT MATCHED THEN

INSERT (column_list) VALUES (column_values);



方案:在alias2中select出来的数据,每一条都跟alias1进行ON (join condition)比较,若匹配,就进行更新操作,不匹配,执行插入操作。merge不会返回影响行数,且最多只能两表关联,适用于连接条件不是主键的字段。

merge into gkfq_rec a

using oa2_ftask b

on (a.slid=b.fi_inst)

when matched then

update set a.blzt=b.ft_lstate;



(4)快速游标更新法(复杂逻辑时,效率很高)

语法:

begin

for cr in (查询语句) loop  --循环

update table_name set ...   --更新语句(根据查询出来的结果集合)

end loop;  --结束循环

end;



方案:配合oracle独有的内置ROWID物理字段,使用快速游标,不需要定义,直接把游标写到for循环中,快速定位并执行更新。它可以支持复杂逻辑的查询语句,更新准确,无论数据多大更新效率依然很高。但执行后不返回影响行数。

begin

for aa in (select a.rowid as rowid,b.ft_lstate as ft_lstate from gkfq_rec a,oa2_ftask b

where a.slid=b.fi_inst ) loop

update gkfq_rec set blzt=aa.ft_lstate

where rowid=aa.rowid;

end loop;

end;



--转自 北京联动北方科技有限公司




赞(0)    操作        顶端 
联动大白
注册用户
等级:列兵
经验:91
发帖:0
精华:0
注册:2015-5-27
状态:离线
发送短消息息给联动大白 加好友    发送短消息息给联动大白 发消息
发表于: IP:您无权察看 2019-6-25 0:30:00 | [全部帖] [楼主帖] 2  楼

为了方便大家阅读,我对文章中错误号来解释一下吧!

Error Id: ORA-01779

Title: cannot modify a column which maps to a non key-preserved table

Description:

cannot modify a column which maps to a non key-preserved table

Action:

Modify the underlying base tables directly.

Cause:

An attempt was made to insert or update columns of a join view which map to a non-key-preserved table.


也许你已明白,但对一个人有用也是我存在的理由!^_^ By:持之以恒的大白

-- 来自: 北京联动北方科技有限公司



赞(0)    操作        顶端 
总帖数
2
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论