2011-04-25 51 views
5

supone que tengo que dar la vuelta a los números de vuelo pares de vuelos que van y vienen de un conjunto de ciudades, así por ejemplo:¿Cómo puedo intercambiar valores de registros en Oracle SQL?

1439 ATL OFS
1440 OFS ATL

terminaría como:

1440 ATL OFS
1439 OFS ATL

probé esta consulta (porque no se puede actualizar .. JOIN en 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; 

donde la aerolínea, flightno es la clave principal para vuelos de mesa. El selecto me da el conjunto correcto de registros que quiero cambiar, pero el ACTUALIZACION ... SET me da este 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 

¿Alguna idea sobre dónde voy mal?

+0

@therin Intenta agregar la restricción al cambio de la tabla añada la restricción flights_uk unique (flightno); –

+0

Añadir una restricción a la vista g He creado? No estoy seguro de lo que quieres decir. He intentado agregar otra restricción a la tabla de vuelos, pero uno de los otros problemas principales con los que he estado tratando es que no puedo agregar una restricción única al número de vuelo, podría haber un número de vuelo idéntico para otra línea aérea. . – therin

+0

@therin Ese es el problema al que se enfrenta porque tiene un número de vuelo idéntico y no puede actualizar –

Respuesta

6

Para actualizar una unión, no importa que el conjunto de datos que está seleccionando se preserva de forma efectiva; Oracle tiene que ser capaz de ver a partir de las restricciones y los predicados que, por definición, se conservará la clave. Y debido a que tiene una condición de desigualdad en el número de vuelo, no hay nada en la definición de datos que garantice que no tendrá múltiples coincidencias para una fila fuente dada.

Si se garantiza que los números de vuelo siempre serán diferentes en 1, es posible que pueda utilizar el método de unión si cambia la condición a d.flightno + 1 = f.flightno.

En cualquier caso, creo que lo siguiente funcionará ... debido a la coherencia de lectura de nivel de estado de cuenta, la subconsulta debería devolver los resultados correctos incluso cuando se actualicen las filas.

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; 
+0

Esto funciona perfectamente, gracias – therin

Cuestiones relacionadas