我有一张桌子
CREATE TABLE foo
(
f0 int,
time_stamp timestamp,
CONSTRAINT foo_pk PRIMARY KEY (f0)
)
我需要大量写入此表,因此性能至关重要。有时,我会写一个具有f0
现有值的记录,并将time_stamp
更新为当前时间。为此,我使用ON CONFLICT..DO UPDATE
子句。
问题是我需要知道INSERT
是否已发生或UPDATE
。
我使用了第二个is_update
列。插入时,插入false
和
`ON CONFLICT .. DO UPDATE set is_update=true`
然后使用RETURNING is_update
来获得我想要的东西。问题在于引入了与数据本身无关的附加列。
答案 0 :(得分:0)
您可以在foo表上创建触发器功能。然后使用TG_OP保留字捕获insert
操作,如果密钥存在则执行更新,否则插入新行。尚未测试大行:)
1.创建程序:
CREATE OR REPLACE FUNCTION public.f0_update_on_duplicate()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
declare _exists boolean;
begin
if TG_OP = 'INSERT' then
select exists(select true from foo where f0 = NEW.f0) into _exists;
raise notice '%', _exists;
if _exists = TRUE then
update foo set time_stamp = NEW.time_stamp where f0 = NEW.f0;
return NULL;
else
return NEW;
end if;
end if;
end
$function$;
2.将程序附加到foo表:
CREATE TRIGGER update_on_duplicate
BEFORE INSERT ON foo FOR EACH ROW EXECUTE PROCEDURE
f0_update_on_duplicate();
3.测试插入。这应该用新的time_stamp更新f0(假设f0 = 5存在于foo表中):
INSERT INTO foo (f0, time_stamp) VALUES ( 5, now() );
答案 1 :(得分:0)
使用两列作为时间戳是常见的做法。
creation_timestamp
列将在插入时设置一次。而 update_timestamp
会将上次覆盖更新的时间戳保留到该记录中。
在每次“更新插入”时,您可以检查 update_timestamp 是否尚未设置。
INSERT INTO foo (f0, creation_timestamp) VALUES (1, NOW())
ON CONFLICT (f0)
DO UPDATE
SET f0=EXCLUDED.f0, update_timestamp=NOW()
RETURNING update_timestamp IS NULL