2012-04-13 14 views
16

que tienen estas tablas:¿Cómo eliminar datos de varias tablas?

 
event  (evt_id, evt_code, reg_id) 

magnitude (mag_id, evt_id, value) 

trace  (trace_id, pt_id) 

point  (pt_id, evt_id) 

quiero borrar todas las filas de todas las tablas relacionadas con evt_id=1139.
¿Cómo lo hago?

Respuesta

17

Si tiene control sobre su esquema, yo haría que el esquema use cascading deletes.

Desde el artículo (la parte más pertinente traducido por tu ejemplo)

CREATE TABLE point 
(
    pt_id integer PRIMARY KEY, 
    evt_id integer REFERENCES event ON DELETE CASCADE 
) 

Si tiene cascadas establecidos, a continuación, puedes eliminar de la tabla de eventos principal y todas las otras mesas se limpiará automáticamente

De lo contrario, primero debe eliminar todas las referencias y luego eliminar la tabla principal. Usted debe hacer esto en una sola transacción para mantener los datos consistentes

BEGIN; 
DELETE FROM trace WHERE EXISTS 
    (SELECT 1 FROM point WHERE evt_id = 1139 AND trace.pt_id = point.pt_id); 
DELETE FROM point where evt_id = 1139; 
DELETE FROM magnitude where evt_id = 1139; 
DELETE FROM event where evt_id = 1139; 
COMMIT; 
-3
$delete = 1139; 
$query = "DELETE FROM event, magnitude, point WHERE evt_id = '$delete'"; 
mysql_query($query, $con); 
$query = "DELETE FROM trace WHERE pt_id = '$delete'"; 

o simplemente pegar esa declaración en un archivo .sql y ejecutarlo, o en su ventana de consulta SQL de software, o colocarlo en un .php archivar y ejecutar en el servidor.

+1

Hasta donde yo sé, no se puede eliminar de varias tablas como esa (pero podría estar equivocado). Sin embargo, al menos 'trace' no tiene una columna evt_id –

+0

La base de datos está en el servidor. ¿Cómo ejecuto este archivo de consulta? – user1202766

+0

Sí, ese rastro verdadero no tiene una columna evt_id pero tiene pt_id que es de la tabla de puntos que tiene la columna evt_id ... ¡eso es confuso! – user1202766

-1

Supongo que los identificadores en las diferentes tablas corresponden y se usan para vincular. También me supuesto de que desea borrar todos los puntos de rastreo acabase sólo están vinculados indirectamente a evt_id

Usted puede borrar sus registros de todas las tablas de la siguiente manera:

DELETE event , magnitude, trace, point 
FROM event left join magnitude on event.evt_id = magnitude.evt_id 
    left join point on event.evt_id = point.evt_id 
     left join trace on point.pt_id = trace.trace_id 
where event_id=1139 
+5

Esto solo funcionará en mysql, y el OP ha vuelto a etiquetar esta pregunta de mysql y postgresql a solo postgresql –

7

El único elemento no trivial en su pregunta son borrados de la tabla trace. Supongo que es seguro asumir que trace.pt_id se está refiriendo a point.pt_id?

Cualquiera que definen un foreign key with ON DELETE CASCADE y simplemente se olvidan de la tabla trace (como ya se ha pointed out by @kevin) o que tiene que cuidar de filas en función manualmente.

Desde PostgreSQL 9.1 puede utilizar data-modifying CTEs:

BEGIN; 

WITH x AS (
    DELETE FROM point WHERE evt_id = 1139 
    RETURNING pt_id 
    ) 
DELETE FROM trace 
USING x 
WHERE trace.pt_id = x.pt_id; 

DELETE FROM magnitude WHERE evt_id = 1139; 

DELETE FROM event WHERE evt_id = 1139; 

COMMIT; 

El RETURNING clauseDELETE FROM point de las declaraciones de todos los afectados pt_id - esos son a su vez se utiliza para eliminar todas las filas correspondientes de trace.

No mencionó si la concurrencia es un problema en su caso. Si es así, y si desea evitar posibles resultados en la ventana de tiempo corto entre las eliminaciones donde las filas para evt_id = 1139 están presentes en una tabla mientras ya se borraron de otra, envuélvalo todo en una transacción .
Si eso no le concierne, ignore BEGIN y COMMIT.

Cuestiones relacionadas