在PostgreSQL中同步两个表

时间:2016-08-10 08:56:18

标签: postgresql plpgsql

我还没有掌握SQL,我想对两个表进行特定的同步:

  • 同步不应该实时发生,它将被触发。
  • 我有一个文本参数可供使用(username)从.txt中提取第二个表
  • 这两个表有两个共同的列:一个是id,另一个是write_datetimestamp without time zone,表示最后一次修改行的时间。所以给定一个id,并且取决于write_date,应该更新第一行或第二行(表格不相同,并且过程不对称)
  • 我真的不知道是否需要创建一个函数,因为我可能会从“psql db_name< / path / to / script”这样的内容中调用更新。我不知道如何以这种方式传递我的参数。

所以我应该这样做:

CREATE OR REPLACE FUNCTION updatedata(username TEXT) RETURNS void AS $$
DECLARE
    row
    data TEXT
    curtime timestamp without time zone := now();
BEGIN
    COPY table2 FROM '/path/to/data/directory' || username || '.txt' DELIMITER ';' CSV;
    FOR row IN
        SELECT table1.id,table1.data1,table2.data2 
        FROM table1 INNER JOIN table2 ON table1.id=table2.id
        WHERE table1.write_date<table2.write_date
    LOOP
        --Process data
        UPDATE table1 SET data1 = data WHERE id = row.id;
        RETURN NEXT row;
    END LOOP;
    --Second FOR/LOOP
END;
$$ LANGUAGE plpgsql;

updatedata('user1');

1 个答案:

答案 0 :(得分:0)

如果我理解正确,您将使用table2作为临时保留表。在这种情况下,您应该在使用前截断它。为了更新主表,您不需要进行循环,您可以使用基于集合的解决方案。你说table1数据列有table2中的三列,所以我假设你需要连接;在我的例子中,我没有包含分隔符,但很容易添加。我认为你需要的是:

CREATE OR REPLACE FUNCTION updatedata(username TEXT) RETURNS void AS $$
DECLARE
    curtime timestamp without time zone := now();
BEGIN
    TRUNCATE TABLE table2;
    COPY table2 FROM '/path/to/data/directory' || username || '.txt' DELIMITER ';' CSV;
    UPDATE table1 t1 
        SET t1.data1 = t2.data1 || t2.data2 || t2.data3, t1.write_date = curtime
        FROM table2 t2 
        WHERE t1.id = t2.id AND t1.username = $1 
        AND t1.write_date < t2.write_date;
END;
$$ LANGUAGE plpgsql;

updatedata('user1'); 

请注意,这只会更新现有记录。如果table2中存在新记录,则不会添加它们。

HTH