postgresql - 更新表逻辑

标签 postgresql postgresql-8.4

我有两个带有触发器的表。

第一个

CREATE OR REPLACE FUNCTION update_table()
RETURNS trigger AS
$BODY$
 BEGIN
IF    TG_OP = 'UPDATE' THEN
    UPDATE filedata SET id=NEW.id,myData=NEW.myData,the_geom=ST_TRANSFORM(NEW.the_geom,70066) WHERE num=NEW.num;
    RETURN NEW;
ELSEIF TG_OP = 'INSERT' THEN
    INSERT INTO filedata(num,id,myData,the_geom) VALUES (NEW.num,NEW.id,NEW.myData,ST_TRANSFORM(NEW.the_geom,70066));
    INSERT INTO filestatus(id,name,status) VALUES (NEW.num,NEW.myData,'Не подтвержден');
    RETURN NEW;
END IF;

 END;
$BODY$
LANGUAGE plpgsql VOLATILE

第二

CREATE OR REPLACE FUNCTION update_table_temp()
RETURNS trigger AS
$BODY$
 BEGIN
IF    TG_OP = 'INSERT' THEN
    INSERT INTO filedata_temp(num,id,myData,the_geom) VALUES (NEW.num,NEW.id,NEW.myData,ST_TRANSFORM(NEW.the_geom,900913));
    RETURN NEW;
ELSEIF TG_OP = 'DELETE' THEN
    DELETE FROM filedata_temp WHERE num=OLD.num;
    RETURN OLD;
END IF;

 END;
$BODY$
LANGUAGE plpgsql VOLATILE

我有一个问题。如果我在第一个表中插入数据,它的触发器也会在第二个表中插入数据。但是该插入会导致第二个表的触发器在第一个表上执行插入操作,依此类推。

你能帮我解决这个问题吗?如何让表在不循环的情况下相互更新?

更新
我有另一个问题 当我在表中插入数据时如何更改数据?例如,我在 the_geom 列中插入 GEOMETRY。如果几何的 SRID=70066 我想将此函数 ST_TRANSFORM(the_geom,900913) 的工作结果放入 the_geom 列。

更新 2

触发器

  CREATE TRIGGER update_geom
  AFTER INSERT
  ON filedata_temp
  FOR EACH ROW
  EXECUTE PROCEDURE update_geom();

函数

 CREATE OR REPLACE FUNCTION update_geom()
 RETURNS trigger AS
 $$
 BEGIN
  IF ST_SRID(NEW.the_geom)=70066 THEN

    UPDATE filedata_temp SET id='88',the_geom=ST_TRANSFORM(NEW.the_geom,900913);
  END IF;
RETURN NEW;

END;
$$
LANGUAGE plpgsql;

如果我使用这个函数触发器不起作用但是如果这样:

 CREATE OR REPLACE FUNCTION update_geom()
 RETURNS trigger AS
 $$
 BEGIN

    UPDATE filedata_temp SET id='88',the_geom=ST_TRANSFORM(NEW.the_geom,900913);
RETURN NEW;

END;
$$
LANGUAGE plpgsql;

我得到 id=88 但 ST_TRANSFORM 不起作用。

更新 3

ST_TRANSFORM() 不错的功能,但在我的情况下它做了一些奇怪的事情。

例如,我有一个表 filedata_temp(SRID=4326)。我使用 srid=70066 插入几何我尝试这个触发器

 CREATE OR REPLACE FUNCTION update_geom()
 RETURNS trigger AS
 $$
 BEGIN

    UPDATE filedata_temp the_geom=ST_TRANSFORM(NEW.the_geom,4326);
RETURN NEW;

END;
$$
LANGUAGE plpgsql;

并得到这个几何体。 "0103000020E6100000010000001800000097832C7ABD823741DA312CBF59F6174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174115B8A7F8208337416DE8C689ADF7174115B8A7F8208337416DE8C689ADF71741D1D3BAF56383374114BFD1303AF917418B016D395F8537413C2856DFF7F717413AF95F044C853741A997BC22A3F71741F88E75BD2D85374178C92D9BE6F61741F92A3B192685374165C8D76E31F61741C84AA37B26853741F2674F6A96F5174144F25B9B16853741E849D10C1BF5174105142CD2E384374112E19E8688F31741B72C78F697843741A808260138F31741FF0C0C6A0884374151A8BBFF76F21741832CF2EEF48337418BE15C1290F21741FFFB3AC6A3833741D85A253DF4F2174113E8B8956C83374109067F2139F31741E383648E3383374100C25C64D8F3174179BAEBD7178337412DA0D6482BF41741CF38E4F7038337410AB04BD7E5F41741C936158CE182374145C1EC5D99F5174197832C7ABD823741DA312CBF59F61741"

ST_transform() 从 SRID=4326 和在 EPSG:70066 中转换的几何体生成这个字符串。

70066中有这个字符串

"0103000020B2110100010000001800000097832C7ABD823741DA312CBF59F6174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174115B8A7F8208337416DE8C689ADF7174115B8A7F8208337416DE8C689ADF71741D1D3BAF56383374114BFD1303AF917418B016D395F8537413C2856DFF7F717413AF95F044C853741A997BC22A3F71741F88E75BD2D85374178C92D9BE6F61741F92A3B192685374165C8D76E31F61741C84AA37B26853741F2674F6A96F5174144F25B9B16853741E849D10C1BF5174105142CD2E384374112E19E8688F31741B72C78F697843741A808260138F31741FF0C0C6A0884374151A8BBFF76F21741832CF2EEF48337418BE15C1290F21741FFFB3AC6A3833741D85A253DF4F2174113E8B8956C83374109067F2139F31741E383648E3383374100C25C64D8F3174179BAEBD7178337412DA0D6482BF41741CF38E4F7038337410AB04BD7E5F41741C936158CE182374145C1EC5D99F5174197832C7ABD823741DA312CBF59F61741"

在 4326

"0103000020E61000000100000018000000AE4F5BA2FC5B4E407E80E7E6F46C4C40F7F1BF79255C4E4019C32D62086D4C40F7F1BF79255C4E4019C32D62086D4C40F7F1BF79255C4E4019C32D62086D4C40A7CE9382325C4E40D8EA369C0D6D4C40A7CE9382325C4E40D8EA369C0D6D4C401BD2B101575C4E4064A420982A6D4C4090DF29FE665D4E4064EE5369116D4C408195B3905C5D4E403664043C0B6D4C4025A00D0E4C5D4E40F7FD7274FD6C4C404201C7B5475D4E409ADF7B26F06C4C403801C7B5475D4E40E43D0EBFE46C4C406EC339053F5D4E404085D2B7DB6C4C40BDFDA836235D4E4001EBC841BE6C4C40685B445FFA5C4E4015C4038EB86C4C40ADB5C108AD5C4E40727935C6AA6C4C408A6B4B9BA25C4E40331ECEACAC6C4C40A7368928775C4E40F7C22E47B46C4C409F640F9D595C4E4077694F81B96C4C40660C21333B5C4E4012EA7C62C56C4C406623646D2C5C4E40CE83E38FCB6C4C4042D9EDFF215C4E40C6A89957D96C4C4095D75EC00F5C4E4013FFA0A5E66C4C40AE4F5BA2FC5B4E407E80E7E6F46C4C40"

最佳答案

你有相互递归的触发器,你想阻止递归。您反而希望触发器仅在用户的直接操作时触发,而不是通过触发器执行的操作。

不幸的是,PostgreSQL 不直接支持你想要的东西,你需要调整你的设计以避免相互递归。

更新问题:在触发器中,更改NEW的内容,例如

IF tg_op = 'INSERT' OR tg_op = 'UPDATE' THEN
    NEW.the_geom := ST_TRANSFORM(NEW.the_geom,900913)
END IF;

参见 really rather good manual用于触发器。

关于postgresql - 更新表逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11790990/

相关文章:

sql - 统计每周比赛的奖牌数

ruby-on-rails-3.2 - 耙工作 :work gives "PGError: ERROR: SELECT FOR UPDATE/SHARE is not allowed in subqueries"

performance - 为 PostgreSQL 查询选择正确的索引

sql - JSONB ILIKE 索引

ruby-on-rails - 该行代码中排序的是哪个关联?

postgresql - Yesod persistent-postgresql rawSql 查询与列列表通配符产生语法错误

permissions - PostgreSQL - 不一致的 COPY 权限错误

postgresql - 使用 CASE WHEN 选择两列

java - Hibernate:多个 native 查询组合在一起

每行的 PostgreSQL 函数