Вопрос по sql, postgresql – Как удалить данные из нескольких таблиц?

19

У меня есть эти таблицы:

event     (evt_id, evt_code, reg_id)

magnitude (mag_id, evt_id, value)

trace     (trace_id, pt_id)

point     (pt_id, evt_id)

Я хочу удалить все строки из всех таблиц, связанных сevt_id=1139.
Как мне это сделать?

Ваш Ответ

5   ответов
-4
$delete =  1139;
$query = "DELETE FROM event, magnitude, point WHERE evt_id = '$delete'";
mysql_query($query, $con);
$query = "DELETE FROM trace WHERE pt_id = '$delete'";

или в окно запроса программного обеспечения sql, или поместите его в файл .php и запустите на сервере.

Насколько я знаю, вы не можете удалить из нескольких таких таблиц (но я могу ошибаться). Тем не менее, как минимумtrace не имеет столбца evt_id
@JustinPihony, я тоже этого не знал, но похоже, что MySQL поддерживает это -dev.mysql.com/doc/refman/5.5/en/delete.html
База данных находится на сервере. Как мне запустить этот файл запроса? user1202766
@ use, r1202766 Аааа, я не заметил тег mySQL, так как последний тег был postgresql ... который не ... пожалуйста, исправьте ваши теги :)
Да, это правда, у e нет столбца evt_id, но есть pt_id из таблицы точек, в которой есть столбец evt_id. Это сбивает с толку! user1202766
11

аблицы.trace, Я думаю, это безопасно предположитьtrace.pt_id ссылаетсяpoint.pt_id?

Либо вы определяетевнешний ключ сON DELETE CASCADE и просто забудь про столtrace (как ужеуказал @kevin) или вы должны позаботиться о зависимости строк вручную.

С PostgreSQL9.1 ты можешь использовать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;

Возврат изDELETE FROM point возвращает все пострадавшиеpt_id - те, в свою очередь, используются для удаления всех соответствующих строк изtrace.

Вы не упомянули,concurrency это проблема в вашем случае. Если это так, и если вы хотите избежать возможных результатов, в коротком временном окне между удаляется, где строки дляevt_id = 1139 присутствуют в одной таблице, но уже удалены из другой, оберните все это вtransaction.
Если это вас не касается, игнорируйтеBEGIN а такжеCOMMIT.

Избежатьdeadlocks всегда используйте одну и ту же последовательность операторов удаления (во всех одновременных транзакциях). Это позволяет избежать ситуаций, когда одну транзакцию начнут удалять в одной таблице, другую - в другой таблице, а затем каждая будет ожидать другую.

4

которые вы хотите удалить, можно представить в виде иерархии, вы можете определить ограничения FOREIGN KEY для отношений с предложением ON DELETE CASCADE. Удаление строки сверху будет каскадом вниз и удалит их все.

http://www.postgresql.org/docs/9.1/static/ddl-constraints.html#DDL-CONSTRAINTS-FK

18

каскадное удаление.

Из статьи (более подходящая часть переведена для вашего примера)

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

Если у вас настроены каскады, вы можете просто удалить их из основной таблицы событий, а все остальные таблицы будут очищены автоматически

В противном случае вам нужно сначала удалить все ссылки, а затем удалить основную таблицу. Вы должны сделать это за одну транзакцию, чтобы сохранить согласованность данных

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

что идентификаторы в разных таблицах соответствуют и используются для связи. Я также предполагаю, что вы хотите удалить все точки трассировки, хотя они только косвенно связаны с evt_id

Вы можете удалить свои записи из всех таблиц следующим образом:

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
Это будет работать только в mysql, и ОП переназначил этот вопрос с mysql и postgresql только на postgresql

Похожие вопросы