插入后触发,更新相关模型Postgresql

Posted

技术标签:

【中文标题】插入后触发,更新相关模型Postgresql【英文标题】:Trigger after insert, update a related model Postgresql 【发布时间】:2015-05-29 02:40:57 【问题描述】:

这是我第一次创建触发器,所以我有点困惑。我正在关注this guide。

这是我到目前为止所做的:

DROP TRIGGER IF EXISTS "update_metas" ON "post";
CREATE TRIGGER "update_metas"
    AFTER INSERT ON "post"
    FOR EACH ROW EXECUTE PROCEDURE update_post_count();

我有两张桌子:userpost。我需要做的是为每个新创建的post 增加列user.postCount。外键是post.user_id

我正在创建的程序如下:

CREATE FUNCTION update_post_count() RETURNS TRIGGER AS $updates_user_postCount$
    BEGIN
        -- I know that NEW contains the new post info, so I
        -- can gather the user_id by doing NEW.post_id.
        -- 
        -- What exactly should I do here?
        RETURN NEW;
    END;
$updates_user_postCount$ LANGUAGE plpgsql;

我应该如何构建这个程序?我可以直接使用SQL 查询吗,例如:

UPDATE "user"
    SET "user"."post_count" = "user"."post_count" + 1
    WHERE "user"."_id" = NEW.idol_id;

更新

我尝试在过程中使用该 SQL 语句,但它返回错误 error: column "user" of relation "user" does not exist

这是我用来创建userpost 表的SQL 语句:

CREATE TABLE IF NOT EXISTS "user" (
    _id BIGSERIAL UNIQUE,
    __id TEXT UNIQUE,
    fbid VARCHAR(100),
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    password VARCHAR(512) NOT NULL,
    profile_picture VARCHAR(512),
    profile_cover VARCHAR(512),
    profile_about TEXT,
    profile_birth_date BIGINT,
    social_facebook VARCHAR(256),
    social_twitter VARCHAR(256),
    social_instagram VARCHAR(256),
    post_count BIGINT,
    highlighted BOOLEAN,
    idol BOOLEAN,
    free BOOLEAN,
    blocked BOOLEAN
);

CREATE TABLE IF NOT EXISTS "post" (
    _id BIGSERIAL UNIQUE,
    __id TEXT UNIQUE,
    idol_id BIGINT,
    removed BOOLEAN,
    free BOOLEAN,
    created_at BIGINT,
    hashtags VARCHAR(1024),
    audio_src VARCHAR(512),
    audio_size INTEGER,
    audio_length INTEGER,
    FOREIGN KEY ("idol_id") REFERENCES "user"("_id")
);

【问题讨论】:

【参考方案1】:

您的触发函数基本正确。唯一的问题是UPDATE 语句不能使用table.column 表示法。

来自documentation:不要在目标列的规范中包含表的名称——例如,UPDATE tab SET tab.col = 1 是无效的。

CREATE FUNCTION update_post_count() RETURNS TRIGGER AS $updates_user_postCount$
BEGIN
  UPDATE "user"
  SET "post_count" = "post_count" + 1
  WHERE "_id" = NEW.idol_id;
  RETURN NEW;
END;
$updates_user_postCount$ LANGUAGE plpgsql;

【讨论】:

我已在您的回答中添加了有关使用 FOR EACH ROW 而不是 FOR EACH STATEMENT 的信息,否则 NEW 为 NULL。见:***.com/questions/11001118/…

以上是关于插入后触发,更新相关模型Postgresql的主要内容,如果未能解决你的问题,请参考以下文章

更新/插入/删除表中的行后触发的触发器有问题

从插入触发器更新时更新触发器后不触发

插入后PostgreSQL触发函数更新

插入和更新后未触发 SQL Server 触发器

如何使用插入触发器后更新表字段?

插入后MySql触发器更新选择总和