PostgreSQL 在触发器函数中声明和使用串行变量

PostgreSQL declaring and use serial variables inside trigger function

CREATE OR REPLACE FUNCTION function_create_forum()
  RETURNS trigger AS
  $$
  BEGIN
    DECLARE  id_course   serial; 

    select id INTO id_course   FROM INSERTED;

    insert INTO Forum (course,name,type,staff_only) VALUES 
                      (id_course,"Staff lounge",1,true);
    --forum 2 creation
    --forum 3 creation

  END;
  $$
  LANGUAGE plpgsql VOLATILE;

只要创建了课程,触发器函数就应该创建一个新论坛,该课程有一个 "id" 字段,它是连续的,这会导致问题,因为在 "DECLARE" 区域内不被接受.

因为在评论中有人继续指出上面的语法是不正确的(不管它在所有其他不使用 "serial" 的触发器中工作正常)这里是代码的另一个变体不起作用。

CREATE OR REPLACE FUNCTION function_create_forum()
  RETURNS trigger AS
  $$
  DECLARE
    id_course int;
  BEGIN

    select id INTO id_course   FROM INSERTED; 

    insert INTO Forum (course,name,type,staff_only) VALUES 
                      (id_course,"Staff lounge",1,true);
    --forum 2 creation
    --forum 3 creation

  END;
  $$
  LANGUAGE plpgsql VOLATILE;

table创作:

CREATE TABLE Forum (
    course serial REFERENCES Course(id) ON DELETE CASCADE NOT NULL,
    --omitted details
);

CREATE TABLE Course (
    id   serial  UNIQUE NOT NULL, --the primary key is another column
    --omitted details
)

正如其他人已经评论的那样,没有 "data type" 连续剧。

Quote from the manual:

The data types smallserial, serial and bigserial are not true types, but merely a notational convenience for creating unique identifier columns (similar to the AUTO_INCREMENT property supported by some other databases)

强调我的

我能看到的一个基本问题是这一行:

select id INTO id_course   FROM INSERTED; 

Postgres 中没有 "inserted" 虚拟 table(例如在 SQL 服务器中)如果您创建行级触发器,那么您可以访问新的值使用 NEW 变量 which is implicitly defined in a trigger function.

的行

另一个问题是"Staff lounge"。双引号用于表示列(或 table)名称,而不是字符文字。 Character literals are enclosed in single quotes in SQL.

所以你的触发函数应该是这样的:

CREATE OR REPLACE FUNCTION function_create_forum()
  RETURNS trigger AS
  $$
  BEGIN

    insert INTO Forum (course,name,type,staff_only) VALUES 
                      (new.id,'Staff lounge',1,true);
    --forum 2 creation
    --forum 3 creation

  END;
  $$
  LANGUAGE plpgsql VOLATILE;

您没有向我们展示您的 create trigger 语句,但它应该是这样的,以确保您正在创建行级触发器:

CREATE TRIGGER course_insert_trg 
   AFTER INSERT ON course  --<< AFTER is important!
   FOR EACH ROW ---<<< this makes it a row level trigger
   EXECUTE PROCEDURE function_create_forum();