Question

I have these tables:

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

What i'm trying to do is to delete a movies row, delete also the related rows from the junction table (movie_cast). And finally delete, from actors table, all the rows that are not referenced in the movie_cast table.

this is the tables schema:

 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);

right now, when the user deletes a movies entry, movie_cast rows referencing the movies._id are also deleted. (i had some troubles with that, but then i used "PRAGMA foreign_keys = ON;" ) so far so good! To delete the actors rows, i thought i could create a trigger that tries to delete actors entries based on the movie_cast.actor_id we just deleted, but since i'm using "ON DELETE RESTRIC", if the actor has still a reference it would abort the delete.

But i'm not even being able to prove it, because i'm getting an error when creating the trigger:

 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)

It seems, it doesn't know what OLD is. What am i doing wrong here?

UPDATE:

It looks like a sqlite configuration problem. I'm using DBeaver SQLite 3.8.2, and it seems to be a problem with the temporary file, but to be honest i don't know how to fix it even reading the possible solution:

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

So, I am going to assume it works and try it directly on my android app.

Was it helpful?

Solution

It was something really s****p. For DBeaver the trigger creation is a complex-statement, and delimiters were not working either, so it was needed to select the whole statement then press ctrl+enter.

Anyway, the statement works. But for a better results I got rid of "ON DELETE RESTRICT" from movie_cast.actor_id. and created a conditional trigger, that executes the delete from actors table, only when there are no more actor_ids equal to the one just deleted(OLD):

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top