gpt4 book ai didi

postgresql - 获取行以在特定条件下交换表

转载 作者:行者123 更新时间:2023-11-29 11:50:52 27 4
gpt4 key购买 nike

我目前有一个父表:

CREATE TABLE members (
member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
first_name varchar(20)
last_name varchar(20)
address address (composite type)
contact_numbers varchar(11)[3]
date_joined date
type varchar(5)
);

和两个相关表:

CREATE TABLE basic_member (
activities varchar[3])
INHERITS (members)
);

CREATE TABLE full_member (
activities varchar[])
INHERITS (members)
);

如果类型是full,详细信息将输入到full_member 表中,或者如果类型是basic,则输入到basic_member表。我想要的是,如果我运行更新并将类型更改为 basicfull,元组将进入相应的表。

我想知道我是否可以使用如下规则来做到这一点:

 CREATE RULE tuple_swap_full
AS ON UPDATE TO full_member
WHERE new.type = 'basic'
INSERT INTO basic_member VALUES (old.member_id, old.first_name, old.last_name,
old.address, old.contact_numbers, old.date_joined, new.type, old.activities);

...然后从full_member中删除记录

只是想知道我的规则是否接近或是否有更好的方法。

最佳答案

  • 你不需要

    member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY

    PRIMARY KEY 自动暗示 UNIQUE NOT NULL:

    member_id SERIAL PRIMARY KEY
  • 我不会使用 varchar(20) 的硬编码最大长度。只需使用 text如果您确实必须强制执行最大长度,则添加检查约束。更容易改变。

  • 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);

触发函数:

Data-modifying CTEs (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;

关于postgresql - 获取行以在特定条件下交换表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10268073/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com