У меня есть база данных SQLite3, которая для оптимизации производительности использует вычисляемые столбцы, обновляемые триггерами.
Теперь я пытаюсь добавить триггер, аналогичный этому (непроверенному, но, вероятно, действительному) коду ORM SQLAlchemy.
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
, помимо простого решения проблемы, я также был бы признателен за ее знание. Даже если бы это сработало, это было бы очень уродливое решение по сравнению с худшим из остальных моих триггеров.
link_type
имеет какое-то значение, кроме столбцаread_free
и первичного ключа с именемid
, на который ссылаетсяlinks
. - person ssokolow   schedule 17.12.2010