使用Oracle数据库的JOIN语法更新

时间:2016-05-03 10:03:17

标签: oracle join sql-update oracle12c

首先,我执行以下SQL语句。

drop table names;
drop table ages;

create table names (id number, name varchar2(20));
insert into names values (1, 'Harry');
insert into names values (2, 'Sally');
insert into names values (3, 'Barry');

create table ages (id number, age number);
insert into ages values (1, 25);
insert into ages values (2, 30);
insert into ages values (3, 35);

select * from names;
select * from ages;

结果,创建了以下表格。

        ID NAME
---------- ----------
         1 Harry
         2 Sally
         3 Barry

        ID        AGE
---------- ----------
         1         25
         2         30
         3         35

现在,我想更新Sally的年龄增加1,即将其设置为31.以下查询正常。

update ages set age = age + 1 where id = (select id from names where name = 'Sally');
select * from ages;

该表现在看起来像这样。

        ID        AGE
---------- ----------
         1         25
         2         31
         3         35

我想知道是否有一种方法可以通过连接来完成。例如,我尝试了以下查询但它们失败了。

SQL> update ages set age = age + 1 from ages, names where ages.id = names.id and names.name = 'Sally';
update ages set age = age + 1 from ages, names where ages.id = names.id and names.name = 'Sally'
                              *
ERROR at line 1:
ORA-00933: SQL command not properly ended


SQL> update ages set age = age + 1 from names join ages on ages.id = names.id where names.name = 'Sally';
update ages set age = age + 1 from names join ages on ages.id = names.id where names.name = 'Sally'
                              *
ERROR at line 1:
ORA-00933: SQL command not properly ended

1 个答案:

答案 0 :(得分:0)

UPDATE语句的语法是:

http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_10007.htm

enter image description here

其中dml_table_expression_clause是:

enter image description here

请注意以上语法的( subquery )部分。

subquery是一项允许执行连接更新的功能。

最简单的形式可以是:

UPDATE (
   subquery-with-a-join
)
SET cola=colb

在更新联接之前,您必须知道此处列出的限制:

https://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_8004.htm

  
    

视图不得包含以下任何构造:

  
     
      
  • 设置运算符
  •   
  • DISTINCT运算符
  •   
  • 汇总或分析功能
  •   
  • GROUP BY,ORDER BY,MODEL,CONNECT BY或START WITH子句
  •   
  • SELECT列表中的集合表达式
  •   
  • SELECT列表中的子查询
  •   
  • 指定为WITH READ ONLY的子查询
  •   
  • 加入,但有一些例外情况,如“Oracle数据库管理员指南”中所述。
  •   

以及与可更新视图相关的常见规则 - 此处(部分:Updating a Join View):
http://docs.oracle.com/cd/B19306_01/server.102/b14231/views.htm#sthref3055

  

连接视图的所有可更新列都必须映射到a的列   钥匙保存的桌子。有关讨论,请参阅“密钥保留表”   密钥保留表。如果使用WITH CHECK定义视图   OPTION子句,然后是所有连接列和重复的所有列   表格不可更新。

我们可以先创建一个带连接的子查询:

SELECT age 
FROM ages a
JOIN names m ON a.id = m.id
WHERE m.name = 'Sally'

此查询只返回以下结果:

       AGE
----------
        30

现在我们可以尝试更新我们的查询:

UPDATE (
    SELECT age 
    FROM ages a
    JOIN names m ON a.id = m.id
    WHERE m.name = 'Sally'
)
SET age = age + 1;

但我们收到错误:

  

SQL错误:ORA-01779:无法修改映射到非密钥保留表的列

此错误表示上述限制之一不符合(密钥保留表)。

但是,如果我们将主键添加到表中:

alter table names add primary key( id );
alter table ages add primary key( id );

然后现在更新工作没有任何错误,最终结果是:

select * from ages;

        ID        AGE
---------- ----------
         1         25
         2         31
         3         35