ITPub博客

首页 > 数据库 > Oracle > [20170513]update结果集.txt

[20170513]update结果集.txt

原创 Oracle 作者:lfree 时间:2017-05-14 21:47:11 0 删除 编辑
[20170513]update结果集.txt

--//前一阵子要对收费价格进行大量调整,当时开发随手写的sql非常不好,我建议通过结果集来修改,这样简单不容易出错.
--//通过例子说明:

1.环境:
SCOTT@test01p> @/ver1
PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.1.0.1.0     Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production              0

create table t1 ( id number ,name  varchar2(20);
insert into t1 values (1,'a');
insert into t1 values (2,'b');
insert into t1 values (3,'c');
insert into t1 values (4,'d');

create table t2 ( id number ,name varchar2(20));
insert into t2 values (2,'bb');
insert into t2 values (3,'cc');

--//实现目的是id相同值使用,使用t2表的name替换原来的t1表的name值.

2.查询:
SCOTT@test01p> select t1.id,t1.name t1name ,t2.id ,t2.name t2name from t1,t2 where t1.id=t2.id;
        ID T1NAME                       ID T2NAME
---------- -------------------- ---------- --------------------
         2 b                             2 bb
         3 c                             3 cc


--//直接使用update对结果集修改:

update
(select t1.id,t1.name t1name ,t2.id ,t2.name t2name from t1,t2 where t1.id=t2.id)
set t1name=t2name;

    *
ERROR at line 3:
ORA-01779: cannot modify a column which maps to a non key-preserved table

SCOTT@test01p> host oerr ora 01779
01779, 00000, "cannot modify a column which maps to a non key-preserved table"
// *Cause: An attempt was made to insert or update columns of a join view which
//         map to a non-key-preserved table.
// *Action: Modify the underlying base tables directly.

--//主要问题我现在2个表没有主键.建立主键就ok了.
SCOTT@test01p> create unique index pk_t1 on t1(id);
Index created.

SCOTT@test01p> create unique index pk_t2 on t2(id);
Index created.

SCOTT@test01p> alter table t1 add constraint pk_t1 primary key (id) enable validate;
Table altered.

SCOTT@test01p> alter table t2 add constraint pk_t2 primary key (id) enable validate;
Table altered.

SCOTT@test01p> update (select t1.id,t1.name t1name ,t2.id ,t2.name t2name from t1,t2 where t1.id=t2.id) set t1name=t2name;
2 rows updated.

SCOTT@test01p> select * from t1;
        ID NAME
---------- --------------------
         1 a
         2 bb
         3 cc
         4 d
--//可以发现只要建立主键.没有问题.
SCOTT@test01p> rollback ;
Rollback complete.

--//这样操作既简单也不容易出错.update的是结果集,而且多数情况先查询看看.前提条件是通过主键连接两个表.

3.注意一些开发这样写是错误的.
SCOTT@test01p> update t1 set name =(select name from t2 where t1.id=t2.id);
4 rows updated.

--//我以前就遭遇过这样的错误,小心小心!!修改4条记录.
SCOTT@test01p> select * from t1;
        ID NAME
---------- --------------------
         1
         2 bb
         3 cc
         4
SCOTT@test01p> rollback ;
Rollback complete.

--//ID=1,4 的name被替换为NULL.必须满足在t2表存在的id修改.应该写成如下:

SCOTT@test01p> update t1 set name =(select name from t2 where t1.id=t2.id) where exists(select name from t2 where t1.id=t2.id);
2 rows updated.

SCOTT@test01p> select * from t1;
        ID NAME
---------- --------------------
         1 a
         2 bb
         3 cc
         4 d

SCOTT@test01p> rollback ;
Rollback complete.

4.还有一种就是使用merge,我觉得我们开发很少使用merge.我自己也很少用.还是上面的方法简单实用,不会出错.
--//而且我们的程序非常垃圾,经常要求开发修改后台业务数据.我经常先查询出结果,然后写成如下例子:

update (select * from dept where deptno=10) set loc='xxxx';




来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-2139049/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7971771