oracle中update...select

本文介绍了一种使用SQL更新表中部分记录的方法,通过结合子查询和NULL值处理函数nvl,确保只有存在匹配项的记录才会被更新。

比如有两张表

 

USER_CHINESE

ID ZHONGWEN

1 张三

2 李四

3 王五

 

USER_ENGLISH
ID PINYIN
1 zhangsan
2 lisi
4 liuliu

现在我想让USER_CHINESE表中的汉字变成拼音。

sql语句是:
update USER_CHINESE t1
set t1.zhongwen = (select t2.pinyin from USER_ENGLISH t2 where t2.id = t1.id);

这时候,你可能觉得应该update两条。
可是结果是:3条被更新。

看结果:
USER_CHINESE
ID ZHONGWEN
1 zhangsan
2 lisi
3

真的是更新了三条。
由于id=3的没有匹配上,所以id=3的记录的ZHONGWEN字段改成null了。
所以,这点一定要注意。

记住:如果update或delete没有where条件,则一定是全表更新的。

如果你不想更新id=3的记录。sql语句可以这样写:
update USER_CHINESE t1
set t1.zhongwen = (select t2.pinyin from USER_ENGLISH t2 where t2.id = t1.id)
where t1.id ! = 3;
这个时候结果是:2条被更新。
USER_CHINESE
ID ZHONGWEN
1 zhangsan
2 lisi
3 王五

但是,如果我们每次都在update之前都先找一下匹配不上的id,然后加到where条件中,这样肯定不行。
所以,如果你想让能匹配上的记录更新,匹配不上的记录保持不变。sql语句应该这样写:
update USER_CHINESE t1
set t1.zhongwen = nvl((select t2.pinyin from USER_ENGLISH t2 where t2.id = t1.id),t1.zhongwen);
这个时候结果是:3条被更新。
USER_CHINESE
ID ZHONGWEN
1 zhangsan
2 lisi
3 王五
达到目的了。注意这个时候是3条被更新,不是两条。

### OracleUPDATE SET SELECT 的语法与用法 在 Oracle 数据库中,虽然没有直接支持 `UPDATE ... SET ... SELECT` 的语法,但可以通过子查询的方式实现类似的功能。具体来说,可以使用 `UPDATE` 语句结合嵌套的 `SELECT` 子查询来更新目标表中的数据[^2]。 以下是一个详细的说明和示例: #### 语法结构 ```sql UPDATE target_table SET column_name = ( SELECT source_column FROM source_table WHERE condition ) WHERE EXISTS ( SELECT 1 FROM source_table WHERE condition ); ``` - **target_table**: 要更新的目标表。 - **column_name**: 目标表中需要更新的列。 - **source_table**: 提供更新数据的源表。 - **condition**: 定义目标表和源表之间的关联条件。 #### 示例代码 假设存在两个表:`customers` 和 `tmp_cust_city`,其中 `customers` 表存储客户信息,`tmp_cust_city` 表存储客户的临时城市信息。现在需要将 `tmp_cust_city` 中的城市名称更新到 `customers` 表中。 ```sql UPDATE customers a SET a.city_name = ( SELECT b.city_name FROM tmp_cust_city b WHERE b.customer_id = a.customer_id ) WHERE EXISTS ( SELECT 1 FROM tmp_cust_city b WHERE b.customer_id = a.customer_id ); ``` #### 注意事项 1. 如果 `tmp_cust_city` 表中的 `customer_id` 不是唯一键或主键,则可能会导致错误 `ORA-01779: cannot modify a column which maps to a non key-preserved table`。 2. 确保 `customers.customer_id` 和 `tmp_cust_city.customer_id` 都是唯一索引或主键,以避免上述错误。 3. 使用 `EXISTS` 子句确保只有匹配的行才会被更新,从而提高性能。 #### 性能优化 为了减少对源表的多次扫描,可以采用以下方法: - 确保源表和目标表之间通过唯一键或主键进行关联。 - 在源表的相关列上创建索引,以加速查询性能。 ### 更新视图的特殊情况 在 Oracle 中,还可以通过更新视图的方式来实现类似的效果。例如: ```sql UPDATE ( SELECT a.city_name, b.city_name AS new_name FROM customers a JOIN tmp_cust_city b ON b.customer_id = a.customer_id ) temp_view SET temp_view.city_name = temp_view.new_name; ``` 此方法的前提是 `customers.customer_id` 和 `tmp_cust_city.customer_id` 必须是唯一键或主键,否则会触发 `ORA-01779` 错误[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值