-
你不需要
member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
A PRIMARY KEY
暗示UNIQUE NOT NULL
自动地:
member_id SERIAL PRIMARY KEY
我不会使用硬编码的最大长度varchar(20)
。只需使用text http://www.postgresql.org/docs/current/interactive/datatype-character.html如果确实必须强制执行最大长度,请添加检查约束。更容易改变。
-
语法为INHERITS
被损坏了。关键字位于列周围的括号之外。
CREATE TABLE full_member (
activities text[]
) INHERITS (members);
表名不一致(members
member
)。我在测试用例中到处使用单数形式。
最后,我不会使用规则来完成任务。 Atrigger AFTER UPDATE
似乎更可取。
考虑以下
测试用例:
Tables:
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 http://www.postgresql.org/docs/current/interactive/queries-with.html#QUERIES-WITH-MODIFYING (WITH x AS ( DELETE ..
)是实现此目的的最佳工具。需要 PostgreSQL 9.1 或更高版本。
对于旧版本,首先INSERT
then 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;
Trigger:
请注意,它是一个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();
Test:
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;