所以,我有一个表格,描述了一些实体在太空中的位置(为了简单起见,原始问题是相关的)
CREATE TABLE positions(
id VARCHAR (32) UNIQUE NOT NULL,
position VARCHAR (50) NOT NULL
);
我创建了一个触发器,通知每次更新
CREATE TRIGGER position_trigger AFTER UPDATE ON positions
FOR EACH ROW
EXECUTE PROCEDURE notify_position();
和一个功能:
CREATE FUNCTION notify_position() RETURNS trigger AS $$
DECLARE
BEGIN
PERFORM pg_notify(
'positions',
TG_TABLE_NAME || ',id,' || NEW.id || ',position,' || NEW.position
);
RETURN new;
END;
$$ LANGUAGE plpgsql;
如何将功能更改为仅在同一位置的实体很少时才通知。
e.g。更新后考虑一个表
id |positions
-------------
id1 |10
id2 |10
id3 |11
我需要使用字符串'id1,id2'
调用notify可能,我需要以某种方式选择与更新的一个具有相同位置的所有实体并创建它们的列表(包含逗号分隔的ID的字符串)。我怎么能这样做?
答案 0 :(得分:1)
根据我对您的问题的理解,您希望在实体的职位更新时发生以下情况:
您可以在触发器功能中使用string_agg
聚合函数来构建匹配实体的ID列表,然后在调用pg_notify
之前检查其长度:
CREATE FUNCTION notify_position() RETURNS trigger AS $$
DECLARE
colocated_ids TEXT;
BEGIN
-- Construct list of IDs of co-located entities.
colocated_ids := (
SELECT string_agg(id, ',')
FROM positions
WHERE position = NEW.position AND id != NEW.id
);
-- Notify listeners if some co-located entities were found.
IF length(colocated_ids) > 0 THEN
PERFORM pg_notify('positions', colocated_ids);
END IF;
RETURN new;
END;
$$ LANGUAGE plpgsql;
请注意,如果没有AND id != NEW.id
检查,更新实体的ID也会显示在列表中。你可以通过触发BEFORE UPDATE
而不是AFTER UPDATE
来避免这种情况。