update from (view)更新表的条件是一个查询

update from (view)更新表的条件是一个查询

  (2010-12-13 22:36:00)
标签: 

杂谈

分类: 科学工程

update ... from (view)语句更新表的条件是一个查询集

以下操作就是基于oracle,先来说一个常见的update操作
假设表T1,T2,T3,......
表T1有主键T1_PK1,T1_PK2,
表T2有主键T2_PK
首先我们这个比较常用
update T2
set T2.col1 = value
where T2.T2_PK = value;
这个sql的更新语句很常见很基础,但是很多情况下更新的条件不是已知的,需要一个查询来确定,这时候就可以这样写上面的语句了
update T2
set T2.col1 = value
where T2.T2_PK in
(
 --T3.T3_PK和T2.T2_PK是相同的字段
  select T3.T3_PK
 from T3,T4,T5
 --这里写查询的条件
        --where .....
)
这个是单主键表的更新,用一个主键可以确定唯一的数据,但是在多主键中多个主键唯一确定一条数据,这样要更新一条主键唯一标识的数据上面的写法肯定不行。这时候可以利用下面的这种写法:
update T1
set T1.col = value
where T1.T1_PK1 in
(
 select
  T2.T2_PK,--和T1_PK1是相同的字段
  T4.T4_PK --和T1_PK2是相同的字段
 from T2,T3,T4,T5
 where .........--各种条件
 and T1.T1_PK2 = T4.T4_PK --这样就算是和查询结果连接起来的,数据没有多余
);
这个是我写的,是标准的sql,但是感觉比较晦涩,回来问了一下别人,有人告诉我一个方法是下面的,不过我没有试行不行,明天试试

update T1
set T1.col = value
where (T1.T1_PK1,T1.T1_PK2) =
(
 select
  T2.T2_PK,--和T1_PK1是相同的字段
  T4.T4_PK --和T1_PK2是相同的字段
 from T2,T3,T4,T5
 where .........--各种条件
);
这个写法看起来优雅潇洒,简单明白,这个方法我试过之后发现也有个不足,就是=后面的结果只能是单行,如果查询结果是多行的时候把=换成in就可以了。

下面还有几种容易出错或者麻烦的写法
比如这样写
update T1
set T1.col = value
where T1.T1_PK1 in
(
 select
  T2.T2_PK,--和T1_PK1是相同的字段
  T4.T4_PK --和T1_PK2是相同的字段
 from T2,T3,T4,T5
 where .........--各种条件
)
and T1.T1_PK2 in
(
 select
  T2.T2_PK,--和T1_PK1是相同的字段
  T4.T4_PK --和T1_PK2是相同的字段
 from T2,T3,T4,T5
 where .........--各种条件
);
这样写很明显,但是其实是错误的,会更新掉你不希望更新的数据,因为T1_PK1 和T1_PK12唯一标识一条数据,上面的更新会更新许多数据,数据不是T1_PK1和T1_PK2的组合,而是判断T1_PK1和T1_PK2是否存在查询结果中。
还有一种写法
update (
 select
  T1.T1_PK1,--和T1_PK1是相同的字段
  T1.T2_PK2 --和T1_PK2是相同的字段
 from T1,T2,T3,T4,T5
 where .........--各种条件
)
set T1.col = value;
这样也就是网上很多人说的方法,这个方法其实就是更新视图(view),这个方法很容易出错“无法修改与非键值保存表对应的列”,为什么会出现这个错误呢,是因为在查询的视图中用了非主键的连接,这样得出的视图是无法唯一标识数据的,所以更新的时候会出现错误。要避免就需要单独建立一个view,并且设置主键就可以了,但是就为了一个sql中更新一下数据,以后也不常用,为什么要建立一个view呢,如果是大的项目中,遍地的view以后维护的人要被搞死了。

当然t-sql中很简单,有个update from语句,这样就不用这么麻烦了,但是这个语句不是sql标准语句。正如oracle的decode语句一样,换个地方就不行了。所以写的时候尽量用sql标准来写,万一有一天系统迁移的时候能剩不少事情。

转载于:https://www.cnblogs.com/yssshan/p/3977280.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值