【警惕】强化关联更新时where子句范围限定意识

如果在关联更新的过程中没有给出where自己进行限制,后果是什么样的呢?如果没有思考过和实践过和吃过亏的朋友们要提高警惕了。
注意,在关联更新时,一定要制定更新的范围,否则后果不堪设想,也许您会因此从梦中惊醒直奔机房去救火。

1.环境准备,创建两张表T1和T2,并简单初始化几条数据
sec@ora10g> create table t1 (x number(10), y number(10));

Table created.

sec@ora10g> create table t2 (x number(10), y number(10));

Table created.

sec@ora10g> insert into t1 values (1,100);

1 row created.

sec@ora10g> insert into t1 values (2,200);

1 row created.

sec@ora10g> insert into t2 values (1,1111111);

1 row created.

sec@ora10g> commit;

Commit complete.

2.T1和T2表中的内容
sec@ora10g> select * from t1;

         X          Y
---------- ----------
         1        100
         2        200

sec@ora10g> select * from t2;

         X          Y
---------- ----------
         1    1111111

3.直观、惊悚的关联更新结果
sec@ora10g> update t1 set y = (select y from t2 where t1.x=t2.x);

2 rows updated.

sec@ora10g> commit;

Commit complete.

sec@ora10g> select * from t1;

         X          Y
---------- ----------
         1    1111111
         2

update语句的本意是将与T2表中x列值相同的T1表中的数据进行更新,注意x等于2的列不在我们考虑的范围,但是未带where子句的关联更新后的结果是那样的让我们无奈。
仔细想想这是为什么呢?道理很简单,没有给出where子句的update语句一定会对T1表的y列的每个值进行更新,当找到与T2表匹配的记录能够正确更新的情况很好理解,当找不与之匹配的记录时,无法判断应该赋予的内容,当然只能将其置为NULL!

4.正确的关联更新方法
很简单,只要在update的where子句中限定住更新范围即可。
sys@ora10g> roll backup;
Rollback complete.
sys@ora10g> select * from t1;

         X          Y
---------- ----------
         1        100
         2        200

sys@ora10g> select * from t2;

         X          Y
---------- ----------
         1    1111111

sys@ora10g> update t1 set y = (select y from t2 where t1.x=t2.x) where x in ( select x from t2);

1 row updated.

sys@ora10g> select * from t1;

         X          Y
---------- ----------
         1    1111111
         2        200

5.小结
生产数据调整的过程中在“commit;”回车键按下之前一定要再三确认,防止因误修改带来的不必要的麻烦。
如果有条件最好在测试环境中充分测试之后再对生产数据进行调整。

Good luck.

secooler
10.06.08

-- The End --

请使用浏览器的分享功能分享到微信等