【发布时间】:2020-10-30 06:33:04
【问题描述】:
我有两张桌子电影和歌曲。歌曲在电影中有外键。当所有引用电影的歌曲都被删除时,我需要删除电影条目。就像多对一的反向级联一样。
删除歌曲条目时,如果所有歌曲都将被删除,则电影应被删除。
我怎样才能像级联删除一样在 sqlite 上实现这一点?
- 列表项
【问题讨论】:
标签: database sqlite database-design foreign-keys android-room
我有两张桌子电影和歌曲。歌曲在电影中有外键。当所有引用电影的歌曲都被删除时,我需要删除电影条目。就像多对一的反向级联一样。
删除歌曲条目时,如果所有歌曲都将被删除,则电影应被删除。
我怎样才能像级联删除一样在 sqlite 上实现这一点?
【问题讨论】:
标签: database sqlite database-design foreign-keys android-room
AFTER DELETE trigger 有效。示例 sqlite3 shell 会话:
sqlite> PRAGMA foreign_keys=on;
sqlite> CREATE TABLE movies(id INTEGER PRIMARY KEY, name);
sqlite> CREATE TABLE songs(id INTEGER PRIMARY KEY, name, movie_id INTEGER REFERENCES movies(id) ON DELETE CASCADE);
sqlite> CREATE INDEX songs_movie_id_idx ON songs(movie_id);
sqlite> CREATE TRIGGER cleanup_movies AFTER DELETE ON songs WHEN ((SELECT count(*) FROM songs WHERE movie_id=old.movie_id) = 0) BEGIN DELETE FROM movies WHERE id = old.movie_id; END;
sqlite> INSERT INTO movie VALUES (1, 'Some Movie');
sqlite> INSERT INTO song VALUES (1, 'Some Song', 1), (2, 'Some Other Song', 1);
sqlite> DELETE FROM songs WHERE id = 1;
sqlite> SELECT * FROM movies;
id name
---------- ----------
1 Some Movie
sqlite> DELETE FROM songs WHERE id = 2;
sqlite> SELECT * FROM movies;
sqlite>
触发器:
CREATE TRIGGER cleanup_movies AFTER DELETE ON songs
WHEN ((SELECT count(*) FROM songs WHERE movie_id=old.movie_id) = 0)
BEGIN
DELETE FROM movies WHERE id = old.movie_id;
END;
从songs 中删除一行后,如果songs 表中没有与已删除行具有相同movie_id 的行,则从movies 表中删除该ID。
【讨论】: