你不需要
member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
A自动PRIMARY KEY
暗示UNIQUE NOT NULL
:
member_id SERIAL PRIMARY KEY
我不会使用硬编码的最大长度varchar(20)
。如果您确实必须强制执行最大长度,只需使用text
并添加检查约束。更容易改变周围。
for 的语法INHERITS
被破坏。关键字在列周围的括号之外。
CREATE TABLE full_member (
activities text[]
) INHERITS (members);
表名不一致 ( members
<-> member
)。在我的测试用例中,我到处都使用单数形式。
最后,我不会对任务使用规则。触发器AFTER UPDATE
似乎更可取。
考虑以下
测试用例:
表:
CREATE SCHEMA x; -- I put everything in a test schema named "x".
-- DROP TABLE x.members CASCADE;
CREATE TABLE x.member (
member_id SERIAL PRIMARY KEY
,first_name text
-- more columns ...
,type text);
CREATE TABLE x.basic_member (
activities text[3]
) INHERITS (x.member);
CREATE TABLE x.full_member (
activities text[]
) INHERITS (x.member);
触发功能:
数据修改 CTE ( WITH x AS ( DELETE ..
) 是实现此目的的最佳工具。需要 PostgreSQL 9.1 或更高版本。
对于旧版本,首先INSERT
然后DELETE
.
CREATE OR REPLACE FUNCTION x.trg_move_member()
RETURNS trigger AS
$BODY$
BEGIN
CASE NEW.type
WHEN 'basic' THEN
WITH x AS (
DELETE FROM x.member
WHERE member_id = NEW.member_id
RETURNING *
)
INSERT INTO x.basic_member (member_id, first_name, type) -- more columns
SELECT member_id, first_name, type -- more columns
FROM x;
WHEN 'full' THEN
WITH x AS (
DELETE FROM x.member
WHERE member_id = NEW.member_id
RETURNING *
)
INSERT INTO x.full_member (member_id, first_name, type) -- more columns
SELECT member_id, first_name, type -- more columns
FROM x;
END CASE;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;
扳机:
请注意,它是一个AFTER
触发器并且有一个WHEN
条件。
WHEN
条件需要 PostgreSQL 9.0 或更高版本。对于早期版本,您可以将其保留,触发器本身的 CASE 语句会处理它。
CREATE TRIGGER up_aft
AFTER UPDATE
ON x.member
FOR EACH ROW
WHEN (NEW.type IN ('basic ','full')) -- OLD.type cannot be IN ('basic ','full')
EXECUTE PROCEDURE x.trg_move_member();
测试:
INSERT INTO x.member (first_name, type) VALUES ('peter', NULL);
UPDATE x.member SET type = 'full' WHERE first_name = 'peter';
SELECT * FROM ONLY x.member;
SELECT * FROM x.basic_member;
SELECT * FROM x.full_member;