为什么在 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 ...