简体   繁体   中英

How do I swap values of records in Oracle SQL?

I'm supposed to flip flight numbers for pairs of flights going back and forth from a set of cities, so for example:

1439 ATL SFO
1440 SFO ATL

would end up as:

1440 ATL SFO
1439 SFO ATL

I tried this query (because you can't UPDATE .. JOIN in 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;

where airline, flightno is the primary key for table flights. The select gives me the correct set of records that I want to swap on, but the UPDATE... SET gives me this error:

   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

Any ideas on where I'm going wrong?

In order to update a join, it doesn't matter that the dataset you are selecting happens to be effectively key-preserved; Oracle has to be able to see from the constraints and the predicates that it will by definition be key-preserved. And because you have an inequality condition on the flightnumber, there is nothing in the data definition to guarantee that you won't have multiple matches for a given source row.

If it's guaranteed that the flight numbers will always differ by 1, you might be able to use the join method if you change the condition to d.flightno + 1 = f.flightno .

In any case, I think the following will work ... because of statement-level read-consistency the subquery should return correct results even as the rows are updated.

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;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM