假设我有两个表(states
,postal_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';
1条答案
按热度按时间5uzkadbs1#
使用
state_code
的INSERT
语句不会成功,因为您试图插入到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将执行相同的标识状态的工作。