我有两个表,group
和 groupmembers
。在 group
表中插入行时,我还想插入两个值,groupid
(来自组表的 id)和 userid
(id创建组的用户的名称)添加到 groupmembers
表中。这些是表格:
CREATE TABLE <b>groups</b> (
id SERIAL PRIMARY KEY NOT NULL,
name CHARACTER VARYING(255) NOT NULL,
creator CHARACTER VARYING(255) NOT NULL,
role CHARACTER VARYING(100) NOT NULL DEFAULT ('admin'),
createdon TIMESTAMP WITH TIME ZONE DEFAULT now(),
FOREIGN KEY (creator) references users (email) on delete CASCADE
);
CREATE TABLE <b>groupmembers</b> (
id SERIAL PRIMARY KEY NOT NULL,
groupid INTEGER NOT NULL,
userid INTEGER NOT NULL,
createdon TIMESTAMP WITH TIME ZONE DEFAULT now(),
FOREIGN KEY (groupid) references groups (id) on delete CASCADE,
FOREIGN KEY (userid) references users (id) on delete CASCADE
);
CREATE TABLE <b>users</b> (
id SERIAL PRIMARY KEY NOT NULL,
firstname CHARACTER VARYING(255) NOT NULL,
lastname CHARACTER VARYING(255) NOT NULL,
email CHARACTER VARYING(50) UNIQUE NOT NULL,
password CHARACTER VARYING(255) NOT NULL,
registeredon TIMESTAMP WITH TIME ZONE DEFAULT now()
);
插入组表的语句是:
INSERT INTO groups (name, creator) VALUES ($1, $2) RETURNING *;
如何添加另一个插入语句,将值插入到 groupmembers
表的 groupid
和 userid
列中?
我看过这个,但它似乎没有回答我的问题:
PostgreSQL nested INSERTs / WITHs for foreign key insertions
最佳答案
我建议使用 data-modifying CTE 将两个插入包装在单个查询中,例如:
WITH grp_ins AS (
INSERT INTO groups (name, creator)
VALUES ($1, $2)
RETURNING id, creator
)
INSERT INTO groupmembers (groupid, userid)
SELECT g.id, u.id
FROM grp_ins g
JOIN users u ON u.email = g.creator;
由于groups.creator
被定义为NOT NULL
并具有强制引用完整性的FK约束,所以[INNER] JOIN
是好的。否则我会考虑LEFT JOIN
。
很像the answer you referred到。或者这些:
如果由于某种原因,您无法强制执行上述命令(例如嵌套在必须用于插入组
的函数中),下一个最好的事情是一个trigger AFTER INSERT
执行第二个INSERT
。稍微复杂一点,成本也高一些。但这项工作确实:
CREATE OR REPLACE FUNCTION trg_ins_row_in_groupmembers()
RETURNS trigger AS
$func$
BEGIN
INSERT INTO groupmembers (groupid, userid)
SELECT NEW.id, (SELECT u.id FROM users u WHERE u.email = NEW.creator);
RETURN NEW; -- doesn't matter much what you return here
END
$func$ LANGUAGE plpgsql;
以及组
上的AFTER INSERT
触发器:
CREATE TRIGGER groups_ins_aft
AFTER INSERT ON groups
FOR EACH ROW EXECUTE PROCEDURE trg_ins_row_in_groupmembers();
相关:
关于sql - PostgreSQL中如何实现嵌套INSERT语句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55212957/