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" 连续剧。
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();
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" 连续剧。
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();