如何基于外键自动填充QGIS关联SQL数据表字段?
解决PostgreSQL自动填充关联表字段的触发器问题
我来帮你排查下这个触发器失效的问题,你的需求是当在tabela_objecto_area中设置indice_sequencial_po外键时,自动从关联表tabela_is_po拉取对应字段填充tema_po、subtema_po和designacao_po,这个思路是对的,但原触发器代码有几个关键错误:
原代码的问题点
- 触发器时机错误:你用了
AFTER INSERT OR UPDATE,这类触发器是在记录已经写入数据库后执行的,此时你再执行INSERT操作会新增一条重复记录,而不是更新当前需要填充的行。应该改用BEFORE INSERT OR UPDATE,这样可以在记录写入前直接修改要插入/更新的行数据。 - NEW对象引用错误:
NEW代表当前触发操作的行对象,不需要加上表名和 schema 前缀,直接访问NEW.indice_sequencial_po即可,原代码里的NEW.pdm2019.tabela_objecto_area.indice_sequencial_po是错误的写法。 - 数据填充方式错误:你尝试用
INSERT语句新增记录,但我们需要的是给当前行的字段赋值,而非新增行,应该通过查询关联表后直接给NEW对象的字段赋值。
修正后的触发器代码
第一步:创建正确的触发器函数
CREATE OR REPLACE FUNCTION pdm2019.tema_e_subtema_automatico() RETURNS TRIGGER AS $tema_e_subtema_automatico$ BEGIN -- 仅当indice_sequencial_po有值时执行填充 IF NEW.indice_sequencial_po IS NOT NULL THEN -- 从关联表查询对应字段并赋值给当前行的NEW对象 SELECT tema, subtema, designacao INTO NEW.tema_po, NEW.subtema_po, NEW.designacao_po FROM pdm2019.tabela_is_po WHERE indice_sequencial_po = NEW.indice_sequencial_po; -- 处理关联表中无匹配记录的情况(可选) IF NOT FOUND THEN NEW.tema_po := NULL; NEW.subtema_po := NULL; NEW.designacao_po := NULL; END IF; ELSE -- 如果indice_sequencial_po被清空,同步清空关联字段(可选) NEW.tema_po := NULL; NEW.subtema_po := NULL; NEW.designacao_po := NULL; END IF; RETURN NEW; -- 返回修改后的NEW对象,用于写入数据库 END; $tema_e_subtema_automatico$ LANGUAGE plpgsql;
第二步:创建BEFORE触发器
CREATE TRIGGER trigger_tema_subtema_automatico BEFORE INSERT OR UPDATE OF indice_sequencial_po ON pdm2019.tabela_objecto_area FOR EACH ROW EXECUTE PROCEDURE pdm2019.tema_e_subtema_automatico();
关键说明
- 触发器指定了
UPDATE OF indice_sequencial_po,意味着只有当indice_sequencial_po字段被修改时才触发,避免不必要的执行。 - 增加了
NOT FOUND的判断,当关联表中没有匹配的indice_sequencial_po时,会清空目标字段,避免残留旧数据。 - 给函数加上了schema前缀
pdm2019.,确保在正确的命名空间下创建对象。
这样修改后,当你在QGIS中编辑tabela_objecto_area的indice_sequencial_po字段时,对应的tema_po、subtema_po和designacao_po就会自动从关联表拉取数据填充了。
内容的提问来源于stack exchange,提问作者João Pinheiro
相关产品推荐
相关产品推荐

