如何在Oracle SQL中交换记录值?

时间:2011-04-25 22:29:38

标签: sql oracle

我应该为一组城市中来回飞行的航班翻转航班号,例如:

1439 ATL SFO
1440 SFO ATL

最终会成为:

1440 ATL SFO
1439 SFO ATL

我尝试了这个查询(因为你无法在Oracle中更新..加入):

UPDATE
   (SELECT f.airline, f.flightno flightno_f, d.airline, d.flightno flightno_d
       FROM flights f
       INNER JOIN flights d ON f.airline = 9 AND
         f.sourceairport = d.destairport AND
         f.destairport = d.sourceairport AND d.airline = 9
       WHERE d.flightno < f.flightno) g
   SET g.flightno_f = g.flightno_d,
     g.flightno_d = g.flightno_f;

航空公司,flightno是表航班的主要钥匙。 select给了我想要交换的正确记录集,但是UPDATE ... SET给了我这个错误:

   SET g.flightno_f = g.flightno_d,
       *
ERROR at line 7:
ORA-01779: cannot modify a column which maps to a non key-preserved table

关于我哪里出错的任何想法?

1 个答案:

答案 0 :(得分:6)

为了更新连接,您选择的数据集恰好是密钥保留的并不重要; Oracle必须能够从约束和谓词中看出它将根据定义进行密钥保存。并且因为你在flightnumber上有一个不等式条件,所以数据定义中没有任何东西可以保证你不会有给定源行的多个匹配。

如果保证航班号始终相差1,如果您将条件更改为d.flightno + 1 = f.flightno,则可以使用联接方法。

在任何情况下,我认为以下内容都有效...因为语句级读取一致性,即使行更新,子查询也应该返回正确的结果。

UPDATE flights f1
  SET flightno =
    (SELECT flightno
       FROM flights f2
       WHERE f2.airline = f1.airline
         AND f2.sourceairport = f1.destairport
         AND f2.destairport = f1.sourceairport
    )
  WHERE airline = 9;