Update tables logic

我们两清 提交于 2019-12-12 04:33:20

问题


I have two tables with triggers on them.

FIRST

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

SECOND

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

And I have a problem. If I insert data in the first table its trigger inserts data in the second table too. But that insert causes the second table's trigger to do an insert on the first table, and so on.

Can you help me with this? How to can I get the tables to update each other without looping?

UPDATE
i have another problem How to change data when i INSERT it in table? For example i insert GEOMETRY in the_geom column. And if geometry's SRID=70066 i want to put in the_geom column result of working of this function ST_TRANSFORM(the_geom,900913).

UPDATE 2

trigger

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

function

 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;

If i use this function trigger no work but if this:

 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;

i get id=88 but ST_TRANSFORM not work.

UPDATE 3

ST_TRANSFORM() nice function but its do something strange in my case.

For example i have a table filedata_temp(SRID=4326). I Insert geometry with srid=70066 i try this trigger

 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;

And get this geometry. "0103000020E6100000010000001800000097832C7ABD823741DA312CBF59F6174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174115B8A7F8208337416DE8C689ADF7174115B8A7F8208337416DE8C689ADF71741D1D3BAF56383374114BFD1303AF917418B016D395F8537413C2856DFF7F717413AF95F044C853741A997BC22A3F71741F88E75BD2D85374178C92D9BE6F61741F92A3B192685374165C8D76E31F61741C84AA37B26853741F2674F6A96F5174144F25B9B16853741E849D10C1BF5174105142CD2E384374112E19E8688F31741B72C78F697843741A808260138F31741FF0C0C6A0884374151A8BBFF76F21741832CF2EEF48337418BE15C1290F21741FFFB3AC6A3833741D85A253DF4F2174113E8B8956C83374109067F2139F31741E383648E3383374100C25C64D8F3174179BAEBD7178337412DA0D6482BF41741CF38E4F7038337410AB04BD7E5F41741C936158CE182374145C1EC5D99F5174197832C7ABD823741DA312CBF59F61741"

ST_transform() make this string from SRID=4326 and geometry which transform in EPSG:70066.

There is this string in 70066

"0103000020B2110100010000001800000097832C7ABD823741DA312CBF59F6174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174145ED23E0088337413CB8228A65F7174115B8A7F8208337416DE8C689ADF7174115B8A7F8208337416DE8C689ADF71741D1D3BAF56383374114BFD1303AF917418B016D395F8537413C2856DFF7F717413AF95F044C853741A997BC22A3F71741F88E75BD2D85374178C92D9BE6F61741F92A3B192685374165C8D76E31F61741C84AA37B26853741F2674F6A96F5174144F25B9B16853741E849D10C1BF5174105142CD2E384374112E19E8688F31741B72C78F697843741A808260138F31741FF0C0C6A0884374151A8BBFF76F21741832CF2EEF48337418BE15C1290F21741FFFB3AC6A3833741D85A253DF4F2174113E8B8956C83374109067F2139F31741E383648E3383374100C25C64D8F3174179BAEBD7178337412DA0D6482BF41741CF38E4F7038337410AB04BD7E5F41741C936158CE182374145C1EC5D99F5174197832C7ABD823741DA312CBF59F61741"

And in 4326

"0103000020E61000000100000018000000AE4F5BA2FC5B4E407E80E7E6F46C4C40F7F1BF79255C4E4019C32D62086D4C40F7F1BF79255C4E4019C32D62086D4C40F7F1BF79255C4E4019C32D62086D4C40A7CE9382325C4E40D8EA369C0D6D4C40A7CE9382325C4E40D8EA369C0D6D4C401BD2B101575C4E4064A420982A6D4C4090DF29FE665D4E4064EE5369116D4C408195B3905C5D4E403664043C0B6D4C4025A00D0E4C5D4E40F7FD7274FD6C4C404201C7B5475D4E409ADF7B26F06C4C403801C7B5475D4E40E43D0EBFE46C4C406EC339053F5D4E404085D2B7DB6C4C40BDFDA836235D4E4001EBC841BE6C4C40685B445FFA5C4E4015C4038EB86C4C40ADB5C108AD5C4E40727935C6AA6C4C408A6B4B9BA25C4E40331ECEACAC6C4C40A7368928775C4E40F7C22E47B46C4C409F640F9D595C4E4077694F81B96C4C40660C21333B5C4E4012EA7C62C56C4C406623646D2C5C4E40CE83E38FCB6C4C4042D9EDFF215C4E40C6A89957D96C4C4095D75EC00F5C4E4013FFA0A5E66C4C40AE4F5BA2FC5B4E407E80E7E6F46C4C40"


回答1:


You have mutually recursive triggers and you want to prevent the recursion. Your instead want a trigger to fire only on a direct action from a user, not an action via a trigger.

Unfortunately, PostgreSQL doesn't directly support what you want, you'll need to tweak your design to avoid the mutual recursion.

Updated question: In a trigger, alter the contents of NEW, eg

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

See the really rather good manual for triggers.




回答2:


        -- The scenario is:
        -- for UPDATEs we use an "alternating bit protocol"
        -- (could also be done by bumping and synchronisng a serial number)
        -- For INSERTs: we only test for NOT EXISTS.
        -- DELETEs are not yet implemented.
        -- *******************************************************************
DROP SCHEMA tmp CASCADE;
CREATE SCHEMA tmp ;
SET search_path=tmp;

        --
        -- Tables for test: we convert int <<-->> text
        --
CREATE TABLE one
        ( id INTEGER NOT NULL PRIMARY KEY
        , flipflag boolean NOT NULL default false
        , ztext varchar
        );
CREATE TABLE two
        ( id INTEGER NOT NULL PRIMARY KEY
        , flipflag boolean NOT NULL default false
        , zval INTEGER
        );
        ------------------------
CREATE function func_one()
RETURNS TRIGGER AS $body$
BEGIN

IF tg_op = 'INSERT' THEN

        INSERT INTO two (id,zval)
        SELECT NEW.id, NEW.ztext::integer
        WHERE NOT EXISTS (
                SELECT * FROM two WHERE two.id = NEW.id)
                ;
ELSIF tg_op = 'UPDATE' THEN

        UPDATE two
        SET zval = NEW.ztext::integer
        , flipflag = NOT flipflag
        WHERE two.id = NEW.id
                ;
END IF;

        RETURN NEW;
END;

$body$
language plpgsql;
CREATE TRIGGER trig_one_i
        AFTER INSERT ON one
        FOR EACH ROW
        EXECUTE PROCEDURE func_one()
        ;

CREATE TRIGGER trig_one_u
        AFTER UPDATE ON one
        FOR EACH ROW
        WHEN (NEW.flipflag = OLD.flipflag)
        EXECUTE PROCEDURE func_one()
        ;

        ------------------------
CREATE function func_two()
RETURNS TRIGGER AS $body$
BEGIN

IF tg_op = 'INSERT' THEN
        INSERT INTO one (id,ztext)
        SELECT NEW.id, NEW.zval::varchar
        WHERE NOT EXISTS (
                SELECT * FROM one WHERE one.id = NEW.id)
                ;
ELSIF tg_op = 'UPDATE' THEN
        UPDATE one
        SET ztext = NEW.zval::varchar
        , flipflag = NOT flipflag
        WHERE one.id = NEW.id
                ;
END IF;

        RETURN NEW;
END;

$body$
language plpgsql;

CREATE TRIGGER trig_two_i
        AFTER INSERT ON two
        FOR EACH ROW
        EXECUTE PROCEDURE func_two()
        ;
CREATE TRIGGER trig_two_u
        AFTER UPDATE ON two
        FOR EACH ROW
        WHEN (NEW.flipflag = OLD.flipflag)
        EXECUTE PROCEDURE func_two()
        ;        --
        -- enter some data
        --
INSERT INTO one (id,ztext)
select gs, gs::text
FROM generate_series(1,10) gs
        ;

        -- Change some data
UPDATE one SET ztext=100 where id = 1;
UPDATE two SET zval=10*zval where id IN (2,4,6,8,10);
INSERT INTO two (id, zval) VALUES(11,14);

SELECT * FROM one ORDER BY id;
SELECT * FROM two ORDER BY id;

RESULT:

NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "one_pkey" for table "one"
CREATE TABLE
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "two_pkey" for table "two"
CREATE TABLE
CREATE FUNCTION
CREATE TRIGGER
CREATE TRIGGER
CREATE FUNCTION
CREATE TRIGGER
CREATE TRIGGER
INSERT 0 10
UPDATE 1
UPDATE 5
INSERT 0 1
 id | flipflag | ztext 
----+----------+-------
  1 | f        | 100
  2 | t        | 20
  3 | f        | 3
  4 | t        | 40
  5 | f        | 5
  6 | t        | 60
  7 | f        | 7
  8 | t        | 80
  9 | f        | 9
 10 | t        | 100
 11 | f        | 14
(11 rows)

 id | flipflag | zval 
----+----------+------
  1 | t        |  100
  2 | f        |   20
  3 | f        |    3
  4 | f        |   40
  5 | f        |    5
  6 | f        |   60
  7 | f        |    7
  8 | f        |   80
  9 | f        |    9
 10 | f        |  100
 11 | f        |   14
(11 rows)


来源:https://stackoverflow.com/questions/11790990/update-tables-logic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!