postgresql - Postgres 计数插入/更新的记录
问题描述
我正在尝试跟踪我们与之同步的客户数据库。我需要将records_added
(INSERTs) 和records_updated
(UPDATEs) 记录到我们的表中。
我正在使用一个UPSERT
来处理同步,并使用一个触发器来更新一个跟踪插入/更新的表。
问题是计算已更新的记录。我有 40 多列要检查,我必须将所有这些都放在我的检查逻辑中吗?有没有更优雅的方式?
有问题的代码部分:
select
case
when old.uuid = new.uuid
and (
old.another_field != new.another_field,
old.and_another_field != new.and_another_field,
-- many more columns here << This is particularly painful
) then 1
else 0
end into update_count;
可重现的例子:
-- create tables
CREATE TABLE IF NOT EXISTS example (uuid serial primary key, another_field int, and_another_field int);
CREATE TABLE IF NOT EXISTS tracker_table (
records_added integer DEFAULT 0,
records_updated integer DEFAULT 0,
created_at date unique
);
-- create function
CREATE OR REPLACE FUNCTION update_records_inserted () RETURNS TRIGGER AS $body$
DECLARE update_count INT;
DECLARE insert_count INT;
BEGIN
-- ---------------- START OF BLOCK IN QUESTION -----------------
select
case
when old.uuid = new.uuid
and (
old.another_field != new.another_field
-- many more columns here
) then 1
else 0
end into update_count;
-- ------------------ END OF BLOCK IN QUESTION ------------------
-- count INSERTs
select
case
when old.uuid is null
and new.uuid is not null then 1
else 0
end into insert_count;
-- --log the counts
-- raise notice 'update %', update_count;
-- raise notice 'insert %', insert_count;
-- insert or update count to tracker table
insert into
tracker_table(
created_at,
records_added,
records_updated
)
VALUES
(CURRENT_DATE, insert_count, update_count) ON CONFLICT (created_at) DO
UPDATE
SET
records_added = tracker_table.records_added + insert_count,
records_updated = tracker_table.records_updated + update_count;
RETURN NEW;
END;
$body$ LANGUAGE plpgsql;
-- Trigger
DROP TRIGGER IF EXISTS example_trigger ON example;
CREATE TRIGGER example_trigger
AFTER
INSERT
OR
UPDATE
ON example FOR EACH ROW EXECUTE PROCEDURE update_records_inserted ();
-- A query to insert, then update when number of uses > 1
insert into example(whatever) values (2, 3) ON CONFLICT(uuid) DO UPDATE SET another_field=excluded.another_field+1;
解决方案
推荐阅读
- c++ - Shell Wrapper 处理/执行交互式命令管道 C++ UNIX
- ruby-on-rails - 转换为 Mongoid 会导致错误:无法加载数据库配置 - 没有这样的文件 - [config/database.yml]
- flutter - 在 VSCode 中调试 Flutter 应用程序时出错
- javascript - 如何在 d3.js 文本属性中添加字符串文本和变量?
- django - ModuleNotFoundError:没有名为“storages.backends.s3boto”的模块
- python - 选择散点图区域内的点
- python - TypeError: __init__() 为参数 'center' 获得了多个值
- azure - 需要在 azure 中创建一个策略,以确保传输中的数据和其余数据被加密
- calendarkit - CalendarKit - EventView 没有成员数据
- java - 无法从数据库中获取对象