У меня есть база данных SQLite3, которая для оптимизации производительности использует вычисляемые столбцы, которые обновляются триггерами.
Я сейчас пытаюсь добавить триггер, который был бы аналогичен этому (непроверенному, но, вероятно, действительному) коду SQLAlchemy ORM
story.read_free = any(link.link_type.read_free for link in story.links)
... но мне трудно понять, как выразить это как UPDATE
предложение. Вот что у меня так далеко:
CREATE TRIGGER IF NOT EXISTS update_link_type AFTER UPDATE ON link_types
FOR EACH ROW WHEN old.read_free <> new.read_free BEGIN
UPDATE stories SET
read_free = CASE WHEN (
SELECT 1 FROM links as l, link_types as lt WHERE lt.id = new.id AND l.link_type_id = lt.id AND l.story_id = stories.id
) THEN 1 ELSE 0 END
WHERE id = (SELECT story_id from links as l, link_types as lt WHERE l.link_type_id = lt.id AND lt.id = new.id)
;
END;
Моя конкретная проблема заключается в том, что я не могу понять, как обеспечить корреляцию подзапроса в CASE
.
Либо SQLite отклоняет синтаксис (такие вещи, как UPDATE foo AS bar
и UPDATE INNER JOIN ...
, которые, очевидно, как вы это делаете на других БД), либо, как в приведенном мной примере, он действителен, но имеет неверное значение. (В этом случае «Установите read_free для этой истории, если существует какой-либо тип ссылки с read_free, независимо от того, есть ли в истории ссылки этого типа)
Если существует более чистая и краткая формулировка этого UPDATE
, помимо простого решения проблемы, я также был бы признателен, если бы знал об этом. Даже если бы это сработало, это было бы очень уродливое решение по сравнению с худшим из остальных моих триггеров.