sql - todos - ¿Cómo borrar datos de varias tablas?
eliminar tabla sql (5)
Tengo estas 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 eliminar todas las filas de todas las tablas relacionadas con evt_id=1139
.
¿Cómo lo hago?
El único elemento no trivial en su pregunta son las eliminaciones de la trace
de la tabla. Supongo que es seguro asumir que trace.pt_id
hace referencia a point.pt_id
?
O bien define una clave foránea con ON DELETE CASCADE
y simplemente se olvida de la trace
la tabla (como ya lo señaló @kevin ) o tiene que ocuparse de las filas manualmente.
Desde PostgreSQL 9.1 puede usar CTE modificadores de datos :
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;
La cláusula RETURNING del DELETE FROM point
devuelve todos los pt_id
afectados, que a su vez se usan para eliminar todas las filas correspondientes de la trace
.
No mencionó si la concurrencia es un problema en su caso. Si es así, y si quiere evitar los posibles resultados en la breve ventana de tiempo entre eliminaciones donde las filas para evt_id = 1139
están presentes en una tabla mientras ya están eliminadas de otra, envuélvalo todo en una transacción .
Si eso no le preocupa, ignore BEGIN
y COMMIT
.
Para evitar puntos muertos, utilice siempre la misma secuencia de declaraciones de eliminación (en todas las transacciones simultáneas). Esto evita situaciones en las que una transacción comenzaría a eliminarse en una tabla, la siguiente en la otra tabla y luego cada una esperaría a la otra.
Si las filas que desea eliminar se pueden visualizar como una jerarquía, podría definir restricciones FOREIGN KEY para las relaciones con la cláusula ON DELETE CASCADE. Eliminar la fila en la parte superior luego caerá en cascada y los eliminará a todos.
http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK
Si tiene control sobre su esquema, haría que el esquema utilice eliminaciones en cascada .
Del artículo (la porción más pertinente traducida para su ejemplo)
CREATE TABLE point
(
pt_id integer PRIMARY KEY,
evt_id integer REFERENCES event ON DELETE CASCADE
)
Si tiene configuradas las cascadas, simplemente puede eliminarlas de la tabla principal de eventos y todas las demás tablas se limpiarán automáticamente
De lo contrario, primero debe eliminar todas las referencias y luego eliminar la tabla principal. Debe hacer esto en una 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;
Supongo que los ID en las diferentes tablas corresponden y se utilizan para vincular. También asumo que desea eliminar todos los puntos de rastreo, aunque solo estén vinculados indirectamente a evt_id
Puede eliminar 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
$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 pegue esa declaración en un archivo .sql y ejecútelo, o en la ventana de consulta del software de su sql, o colóquelo en un archivo .php y ejecútelo en el servidor.