我有两张桌子,一张带有电影列表,另一张带有每部电影播放时的日期列表。电影列表包含name
,id
,start_date
和end_date
列,而id是唯一标识符。
节目列表(包含日期的节目列表)包含id
,movie_id
,date
。
每次INSERT
新节目时,我都希望更新电影列表:如果show.date
位于movie.start_date
之前,我希望{{1}要更新为start_date
的值。结束日期也是如此 - 显然,如果show.date
位于show.date
之后。
以下规则是我所坚持的:(注意:如果它起作用,它只会设置开始日期,一旦完成,结束日期应该很容易......)
movie.end_date
返回:CREATE RULE "movies_start_date_setter" AS ON INSERT TO "shows"
WHERE movies.id = NEW.movie_id AND movies.start_date < NEW.date
DO (UPDATE movies SET start_date = NEW.date);
这个错误不会给我(作为初学者)任何我缺少FROM子句的信息以及原因。
既然每个人似乎都认为一个规则是一个坏主意(我倾向于屈服于压力)我尝试了一个触发器,这对我来说绝对是全新的。
使用触发器(强烈推荐),它看起来像这样:
ERROR: missing FROM-clause entry for table "movies"
其次是:
CREATE OR REPLACE FUNCTION adjust_start_date()
RETURNS trigger AS
$BODY$
BEGIN
UPDATE movies SET start_date = NEW.date
WHERE id = NEW.movie_id AND start_date > NEW.date;
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql';
此触发器可能有效也可能无效,它解决了我的问题,但没有回答我原来的问题...... 还有其他人比我聪明(我当然希望如此!)?
答案 0 :(得分:1)
在movies
子句中未知表where
。使用:
create rule movies_start_date_setter as
on insert to shows do (
update movies
set start_date = new.date
where id = new.movie_id and start_date > new.date
);
答案 1 :(得分:0)
错误消息的共鸣是您在movies
子句中引用表WHERE
。
您可以尝试使用如下的查询重写规则:
CREATE RULE movies_start_date_setter AS
ON INSERT TO shows DO ALSO
UPDATE movies
SET start_date = LEAST(NEW.date, start_date),
end_date = GREATEST(NEW.date, end_date)
WHERE id = NEW.movie_id
AND NEW.date NOT BETWEEN start_date AND end_date;
但这不适用于多行INSERT
,如下所示:
INSERT INTO shows (id, movie_id, date) VALUES
(1, 42, <very small date>),
(2, 42, <very large date>);
因为只有movies
行id = 42
中的一个日期会被更改。
规则很棘手,难以理解。
你最好使用触发器。