开发者社区> 问答> 正文

请教大家一个Oracle子查询更新表的问题:无法修改与非键值保存表对应的列?报错

我在使用Oracle子查询更新表时报错:无法修改与非键值保存表对应的列,报错截图如下:

两个表,如下图:

建表语句如下:

create table test1(id1 int,id2 int,col1 int,col2 int);
create table test2(id1 int,id2 int,v1 int,v2 int);

初始化数据:

insert into test1(id1,id2,col1,col2)values(11,12,1001,1002);
insert into test1(id1,id2,col1,col2)values(13,14,1003,1004);
insert into test1(id1,id2,col1,col2)values(15,16,1005,1006);
 
insert into test2(id1,id2,v1,v2)    values(21,22,2001,2002);
insert into test2(id1,id2,v1,v2)    values(23,24,2003,2004);
insert into test2(id1,id2,v1,v2)    values(25,26,2005,2006);
insert into test2(id1,id2,v1,v2)    values(27,28,2007,2008);

【要求】:使用子查询更新表test1,即,将表test1中的col1字段修改为test2中的v1值;更新条件是test1.id1=test2.id1 and test1.id2=test2.id2。

我的sql语句如下(执行报错,但是不知道原因):

update(
      select t1.col1,tt.v1 from test1 t1, 
      ( select id1,id2,max(v1)v1 from test2 t2
              group by id1,id2
       )tt where t1.id1=tt.id1 and t1.id2=tt.id2      
)t set t.col1=t.v1;

报错截图如下:


请问这种条件如何使用Oracle中的“
子查询更新表”这种语法呢?

我上面的SQL语句应该怎么写呢?

希望哪位能帮忙解决一下,谢谢了!

展开
收起
爱吃鱼的程序员 2020-06-07 17:48:13 1092 0
1 条回答
写回答
取消 提交回答
  • https://developer.aliyun.com/profile/5yerqm5bn5yqg?spm=a2c6h.12873639.0.0.6eae304abcjaIB
                        估计是列名冲突,select后查询项都加上别名 
                    
    
                            跟列名没有关系吧 
                        
    
                        <blockquote>
    

    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.

                            给表增加主键?改变表结构方法肯定是不对的 
                        
    
                        <pre><code>--没见过update后面跟子查询的
    

    update test t1 from ( select id1,id2,max(v1)v1 from test2 t2 group by id1,id2 )tt where t1.id1=tt.id1 and t1.id2=tt.id2
    set t1.col1=tt.v1;

    随手写的,试试看

                        <pre><code>update test1 t1 set t1.col1=(select max(t2.v1) from test2 t2 where t1.id1=t2.id1 and t1.id2=t2.id2)
    

    where exists (select 0 from test2 t2 where t1.id1=t2.id1 and t1.id2=t2.id2);

     

                            我的test2表可能是一个比较复杂的查询语句,所以我才考虑使用update(子查询)这种方式来更新表的。你的方法对我这种情况不适用。
    
    2020-06-07 17:48:31
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
PostgresChina2018_樊文凯_ORACLE数据库和应用异构迁移最佳实践 立即下载
PostgresChina2018_王帅_从Oracle到PostgreSQL的数据迁移 立即下载
Oracle云上最佳实践 立即下载

相关镜像