如何在plpgsql过程中有条件地运行查询

时间:2016-09-26 17:28:15

标签: postgresql plpgsql

我的一些数据模型具有必须在其子项更改时保持更新的关系,例如多点位置,该位置是许多具有点位置的子集的集合,如果子节点被重新定位则必须更新点位置。有多个这样的关系,我想在单个触发器+过程中处理维护这些关系的完整性,该过程在更新父受影响关系的相关字段时触发以下过程。

如何格式化这些查询和条件,以便它完成以下任务:

CREATE TABLE parents (
    id BIGSERIAL PRIMARY KEY,
    caption TEXT,
    title TEXT,
    tags CHARACTER VARYING(32)[] DEFAULT '{}',
    rating SMALLINT DEFAULT 0
)
CREATE TABLE children (
    id BIGSERIAL PRIMARY KEY,
    tags CHARACTER VARYING(32)[] DEFAULT '{}',
    rating SMALLINT DEFAULT 0
)
CREATE TABLE parent_children (
    parent_id BIGINT,
    child_id BIGINT
)

CREATE OR REPLACE FUNCTION child_updated_func() RETURNS TRIGGER AS $$
    BEGIN
        IF (OLD.tags != NEW.tags) 
            UPDATE parents
            SET tags = tags || NEW.tags
            WHERE
                parent_children.child_id =  NEW.id
                AND parents.id = parent_children.parent_id;
        IF (OLD.rating != NEW.rating) 
            UPDATE parents
            SET rating = MAX(parent_children.rating)
            FROM parent_children
            WHERE
                parent_children.child_id = NEW.id
                AND parents.id = parent_children.parent_id;
        RETURN NEW;
    END
$$ LANGUAGE plpgsql;

CREATE TRIGGER child_updated
    AFTER UPDATE ON children
    FOR EACH ROW
    EXECUTE PROCEDURE child_updated_func();

1 个答案:

答案 0 :(得分:1)

你可能想要这样的东西:

CREATE OR REPLACE FUNCTION func() RETURNS TRIGGER AS $$
    BEGIN
        IF (OLD.tags != NEW.tags) THEN
            UPDATE parents
            SET tags = tags || NEW.tags
            WHERE
                parent_children.child_id =  NEW.id
                AND parents.id = parent_children.parent_id;
        END IF;
        IF (OLD.rating != NEW.rating) 
            UPDATE parents
            SET rating = MAX(parent_children.rating)
            FROM parent_children
            WHERE
                parent_children.child_id = NEW.id
                AND parents.id = parent_children.parent_id;
        END IF;
        RETURN NEW;
    END
$$ LANGUAGE plpgsql;