Как можно удалить строку из одной таблицы в PostgreSQL и одновременно добавить эту же строку в другую таблицу?

Подскажите, пожалуйста, как реализовать процесс удаления строки из одной таблицы и добавления этой же строки в другую таблицу? Например, у меня есть активные задачі, которые после выполнения должны перемещаться в архивные. Я видел, что можно создать две таблицы с одинаковой структурой. В этом случае, когда я удаляю задачу из активных, она должна копироваться в архивную таблицу, избегая необходимости передавать данные этой задачи в теле запроса. Как лучше это сделать?
  • 3 декабря 2024 г. 19:33
Ответы на вопрос 3
Для перемещения строки из одной таблицы в другую в PostgreSQL можно использовать транзакции и оператор `INSERT ... SELECT ...` для вставки строки в архивную таблицу перед её удалением из активной таблицы. Вот пример, как это можно сделать.

Предположим, у вас есть две таблицы: `active_tasks` (активные задачи) и `archived_tasks` (архивные задачи). Предположим, у обеих таблиц есть идентификатор `id` и другие поля, например, `task_name`, `status` и т.д.

### Шаги для перемещения строки

1. Создайте транзакцию, чтобы гарантировать атомарность операций.
2. Вставьте строку в архивную таблицу на основе идентификатора или другого уникального поля.
3. Удалите строку из активной таблицы.

### Пример SQL-запроса:

```sql
BEGIN;

-- Вставляем строку из активной таблицы в архивную таблицу
INSERT INTO archived_tasks (id, task_name, status) 
SELECT id, task_name, status 
FROM active_tasks 
WHERE id = :task_id;  -- замените :task_id на актуальный идентификатор задачи

-- Удаляем строку из активной таблицы
DELETE FROM active_tasks 
WHERE id = :task_id;

COMMIT;
```

### Замечания:

- Не забудьте заменить `:task_id` на актуальный идентификатор задачи, который вы хотите переместить. 
- Если у вас есть ограничения на уровне базы данных, такие как внешние ключи, убедитесь, что они не нарушаются.
- Если вы хотите обрабатывать ошибки, можете использовать конструкцию `EXCEPTION` в блоке PL/pgSQL или обрабатывать ошибки в клиентском приложении.
- Также можно использовать триггеры, если нужно автоматизировать этот процесс, но в таком случае правила будут зависеть от вашего конкретного сценария.

### Пример с триггером

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

```sql
CREATE OR REPLACE FUNCTION move_task_to_archive()
RETURNS TRIGGER AS $$
BEGIN
    -- Вставляем строку в архивную таблицу
    INSERT INTO archived_tasks (id, task_name, status)
    VALUES (OLD.id, OLD.task_name, OLD.status);
    
    -- Удаляем строку из активной таблицы
    RETURN OLD; -- Возвращаем удаляемую строку (или NULL для DELETE)
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trigger_move_task_to_archive
AFTER DELETE ON active_tasks
FOR EACH ROW EXECUTE FUNCTION move_task_to_archive();
```

Этот триггер будет срабатывать каждый раз, когда строка удаляется из `active_tasks`, и автоматически перемещать её в `archived_tasks`.
INSERT INTO
  SELECT
DELETE


Но это не правильно. Сделайте в таблице заданий поле-признак выполнения.
триггер на DELETE в первой таблице, в триггере получаешь удаленный row и вставляешь в другую таблицу
Похожие вопросы