Как поменять значения записей в Oracle SQL? - PullRequest
5 голосов
/ 26 апреля 2011

Я должен отразить номера рейсов для пар рейсов, идущих туда и обратно из нескольких городов, например:

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 является основным ключом для настольных рейсов. Выбор дает мне правильный набор записей, на которые я хочу обменяться, но ОБНОВЛЕНИЕ ... 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 Ответ

6 голосов
/ 26 апреля 2011

Чтобы обновить объединение, не имеет значения, что выбранный вами набор данных эффективно сохраняется ключом; Oracle должен иметь возможность видеть из ограничений и предикатов, что он по определению будет сохранен на ключе. А поскольку у вас есть условие неравенства для номера рейса, в определении данных нет ничего, что гарантировало бы, что у вас не будет нескольких совпадений для данной строки источника.

Если гарантировано, что номера рейсов всегда будут отличаться на 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...