创建sqlite触发器时出错

时间:2014-03-21 18:39:44

标签: sql sqlite relational-database

我有这些表格:

 +-------------------------+
 |         Movies          |
 +-----+--------+----------+
 | _id | title  | language |
 +--+--+--------+----------+
    |
    +-------------------------+
                              |
 +----------------------------------+
 |            Movie_Cast            |
 +------------+----------+----------+
 | id         | actor_id | movie_id |
 +------------+-----+----+----------+
                    |
      +-------------+
      |
 +-------------------+
 |      Actors       |
 +----------+--------+
 | actor_id | name   |
 +----------+--------+

我要做的是删除电影行,同时删除联结表中的相关行(movie_cast)。最后从actors表中删除movie_cast表中未引用的所有行。

这是表架构:

 create table movies (_id INTEGER PRIMARY KEY, title TEXT, language TEXT);

 create table movie_cast (id INTEGER PRIMARY KEY, 
      actor_id INTEGER REFERENCES actors(actor_id) ON DELETE RESTRICT, 
      movie_id INTEGER REFERENCES movies(_id) ON DELETE CASCADE);

 create table actors (actor_id INTEGER PRIMARY KEY, actor TEXT UNIQUE);

现在,当用户删除电影条目时,也会删除引用movies._id的movie_cast行。 (我有一些麻烦,但后来我用“PRAGMA foreign_keys = ON;”)到目前为止一切都那么好!要删除actor行,我想我可以创建一个触发器,尝试根据我们刚刚删除的movie_cast.actor_id删除actor条目,但由于我正在使用“ON DELETE RESTRIC”,如果actor还有引用它会中止删除。

但我甚至无法证明它,因为我在创建触发器时遇到错误:

 CREATE TRIGGER Delete_Actors AFTER DELETE ON movie_cast
 FOR EACH ROW
 BEGIN
 DELETE FROM actors WHERE actors.actor_id = OLD.actor_id;
 END;

 SQL Error [1]: [SQLITE_ERROR] SQL error or missing database (near "actor_id": syntax error)
   [SQLITE_ERROR] SQL error or missing database (near "actor_id": syntax error)

看来,它不知道OLD是什么。我在这做错了什么?

更新

它看起来像是一个sqlite配置问题。我正在使用DBeaver SQLite 3.8.2,它似乎是临时文件的问题,但说实话我甚至不知道如何修复它甚至阅读可能的解决方案:

It's failing to create the temporary file required for a statement journal. 
It's likely any statement that uses a temporary file will fail.

   http://www.sqlite.org/tempfiles.html

One way around the problem would be to configure SQLite not to use
temp files using "PRAGMA temp_store = memory;".

Or ensure that the environment variable SQLITE_TMPDIR is set to
the path of a writable directory. See also:

    http://www.sqlite.org/c3ref/temp_directory.html

所以,我会假设它可以直接在我的Android应用程序上试用。

1 个答案:

答案 0 :(得分:0)

这真的是*** *** p。对于DBeaver,触发器创建是一个复杂的语句,分隔符也不起作用,所以需要选择整个语句然后按ctrl + enter。

无论如何,声明有效。但是为了获得更好的结果,我从movie_cast.actor_id中删除了“ON DELETE RESTRICT”。并创建了一个条件触发器,只有当没有更多的actor_ids等于刚刚删除的那个(OLD)时才执行从actors表中删除:

CREATE TRIGGER Delete_Actors 
AFTER DELETE ON movie_cast
FOR EACH ROW
WHEN (SELECT count(id) FROM movie_cast WHERE actor_id = OLD.actor_id) = 0
 BEGIN
    DELETE FROM actors WHERE actors.actor_id = OLD.actor_id;
 END;