为什么在 Postgres 中,table 为空,如果我使用 BEFORE INSERT,则 :NEW: 变量为 NULL?
Why in Postgres, with an empty table, if I use BEFORE INSERT, the :NEW: variable is NULL?
我正在 PostgreSQL 中开发电影数据库。
我有一个触发器,在我插入新节目之前,它会检查节目的日期是否早于电影的发行日期(例如,今天添加 Avatar 2 的节目)。
这是代码:
CREATE TRIGGER beforereleasedate
BEFORE INSERT
ON public.shows
FOR EACH ROW
EXECUTE PROCEDURE public.filmnotreleased();
CREATE FUNCTION public.filmnotreleased()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
var1 DATE;
var2 DATE;
BEGIN
SELECT NEW.ShowDate INTO var1
FROM SHOWS;
SELECT ReleaseDate INTO var2
FROM FILM
WHERE CodF=NEW.CodF;
IF var1<var2
THEN
RAISE EXCEPTION 'Can't add a show of a movie still not released.';
END IF;
RETURN NEW;
END;
$BODY$;
ALTER FUNCTION public.filmnotreleased()
OWNER TO postgres;
事实是,如果 SHOWS table 为空,则 var1 为 NULL。已经用 'raise notice' 检查过。奇怪的是,这只有在 table 为空时才会发生。所以,无论我使用什么日期,第一个插入都是错误的。之后,触发器正常工作,var1不再为NULL,而是我刚刚插入的值。
有什么帮助吗?
部分:SELECT NEW.ShowDate INTO var1 FROM SHOWS;
没有意义。您正在读取 table shows
中的 all 行,以便将一个变量 (new.showdate
) 的值存储到另一个变量 (var1
).显然,如果 table 为空,SELECT 将不会 return 任何行,这意味着 var1
将为空。
但是不需要从 table 显示中读取任何内容,因为您可以通过 new
记录访问当前插入的行。
所以你可能想要这样的东西:
CREATE FUNCTION public.filmnonuscito()
RETURNS trigger
LANGUAGE plpgsql
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
var2 DATE;
BEGIN
SELECT ReleaseDate
INTO var2
FROM FILM
WHERE CodF=NEW.CodF;
IF NEW.showdate < var2
THEN
RAISE EXCEPTION 'Can't add a show of a movie still not released.';
END IF;
RETURN NEW;
END;
$BODY$;
请注意,如果根本没有这样的电影,这将无法处理这种情况。您可能需要添加一个 null
检查来解决这个问题,例如if NEW.showdate < var2 or var2 is null ...
我正在 PostgreSQL 中开发电影数据库。 我有一个触发器,在我插入新节目之前,它会检查节目的日期是否早于电影的发行日期(例如,今天添加 Avatar 2 的节目)。 这是代码:
CREATE TRIGGER beforereleasedate
BEFORE INSERT
ON public.shows
FOR EACH ROW
EXECUTE PROCEDURE public.filmnotreleased();
CREATE FUNCTION public.filmnotreleased()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
var1 DATE;
var2 DATE;
BEGIN
SELECT NEW.ShowDate INTO var1
FROM SHOWS;
SELECT ReleaseDate INTO var2
FROM FILM
WHERE CodF=NEW.CodF;
IF var1<var2
THEN
RAISE EXCEPTION 'Can't add a show of a movie still not released.';
END IF;
RETURN NEW;
END;
$BODY$;
ALTER FUNCTION public.filmnotreleased()
OWNER TO postgres;
事实是,如果 SHOWS table 为空,则 var1 为 NULL。已经用 'raise notice' 检查过。奇怪的是,这只有在 table 为空时才会发生。所以,无论我使用什么日期,第一个插入都是错误的。之后,触发器正常工作,var1不再为NULL,而是我刚刚插入的值。
有什么帮助吗?
部分:SELECT NEW.ShowDate INTO var1 FROM SHOWS;
没有意义。您正在读取 table shows
中的 all 行,以便将一个变量 (new.showdate
) 的值存储到另一个变量 (var1
).显然,如果 table 为空,SELECT 将不会 return 任何行,这意味着 var1
将为空。
但是不需要从 table 显示中读取任何内容,因为您可以通过 new
记录访问当前插入的行。
所以你可能想要这样的东西:
CREATE FUNCTION public.filmnonuscito()
RETURNS trigger
LANGUAGE plpgsql
COST 100
VOLATILE NOT LEAKPROOF
AS $BODY$
DECLARE
var2 DATE;
BEGIN
SELECT ReleaseDate
INTO var2
FROM FILM
WHERE CodF=NEW.CodF;
IF NEW.showdate < var2
THEN
RAISE EXCEPTION 'Can't add a show of a movie still not released.';
END IF;
RETURN NEW;
END;
$BODY$;
请注意,如果根本没有这样的电影,这将无法处理这种情况。您可能需要添加一个 null
检查来解决这个问题,例如if NEW.showdate < var2 or var2 is null ...