postgresql 在postgres中使用触发器可以让insert接受一个新的列,只被lookup id替换吗?

bvn4nwqk  于 2023-06-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(121)

假设我有两个表(statespostal_codes),用户可以在postal_code中插入新的邮政编码及其状态。
| 状态ID|状态码|州名|
| - -----|- -----|- -----|
| 1| 'FL'|佛罗里达|
| 2|“嘎”|'格鲁吉亚'|
| 邮政编码|状态ID|
| - -----|- -----|
| “一二三四五”|1|
| ‘五四三二一’|2|
是否可以使用BEFORE INSERT触发器来允许INSERT INTO命令具有state_code,并且函数将其替换为适当的state_id
我可以做如下事情:

CREATE OR REPLACE FUNCTION insert_postal_code()
RETURNS TRIGGER
AS $$
BEGIN
    SELECT s.state_id
    FROM states s
    WHERE s.state_code = NEW.state_code
    INTO NEW.state_id;
    RAISE NOTICE '%', NEW;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER insert_postal_code_trigger
    BEFORE INSERT
    ON postal_codes
    FOR EACH ROW
    EXECUTE FUNCTION insert_postal_code();

INSERT INTO postal_codes (postal_code, state_code)
VALUES ('12345', 'FL');

还是每次都要将SELECT包含到INSERT中?

INSERT INTO postal_codes (postal_code, state_id)
SELECT '12345', s.state_id
FROM states s
WHERE s.state_code = 'FL';
5uzkadbs

5uzkadbs1#

使用state_codeINSERT语句不会成功,因为您试图插入到postal_codes表中不存在的字段中。
所以,不,照现在的样子,你的努力是行不通的。
对此,我将丢弃状态表中的id字段,并使用state_code作为主键。然后使用state_code作为postal_codes表中的外键。
这使得postal_codes表中的数据更易于阅读(但这是附带的好处)。
INSERT语句将按编写的方式工作。无需触发器。
如果你在一个大型项目中工作,你可能会有一个规则,比如“所有表都必须有一个bigserial(或者像Frank Heikens建议的那样,Identity会更好)id字段,用作PK和FK”。在这种情况下,您不能使用此建议。
如果您真的愿意,可以保留现有结构,但将state_code添加到postal_codes表中。那么INSERT语句和TRIGGER语句就可以工作了。但这将是一个糟糕的数据库设计。所以别这么做。这将是复制数据-postal_codes表中的state_code和state_id将执行相同的标识状态的工作。

相关问题