Postgresql 触发器语法错误位于 "NEW"处或附近

标签 postgresql

这是我正在尝试做的事情:

ALTER TABLE publishroomcontacts ADD COLUMN IF NOT EXISTS contactorder integer NOT NULL default 1;

CREATE OR REPLACE FUNCTION publishroomcontactorder() RETURNS trigger AS $publishroomcontacts$
    BEGIN   
      IF (TG_OP = 'INSERT') THEN
            with newcontactorder as (SELECT contactorder FROM publishroomcontacts WHERE publishroomid = NEW.publishroomid ORDER BY contactorder limit 1)    
            NEW.contactorder = (newcontactorder + 1);
        END IF;
        RETURN NEW;
    END;
$publishroomcontacts$ LANGUAGE plpgsql;

CREATE TRIGGER publishroomcontacts BEFORE INSERT OR UPDATE ON publishroomcontacts
    FOR EACH ROW EXECUTE PROCEDURE publishroomcontactorder();

我研究了很多例子,它们看起来都是这样的。他们中的大多数只有几岁。这已经改变了吗?或者为什么新的不起作用?我是否必须在函数中执行插入操作,还是 postgres 在函数完成后使用返回的 NEW 对象执行插入操作?

最佳答案

我不确定您要做什么,但您的语法在这里是错误的:

with newcontactorder as (SELECT contactorder FROM publishroomcontacts WHERE publishroomid = NEW.publishroomid ORDER BY contactorder limit 1)    
NEW.contactorder = (newcontactorder + 1);

如果后面没有 select,请勿使用 CTE 查询。如果你想增加 contactorder特别专栏publishroomid每当添加新的并且这是您的序列(自动增量)机制时,您应该将其替换为:

NEW.contactorder = COALESCE((
    SELECT max(contactorder)
    FROM publishroomcontacts
    WHERE publishroomid = NEW.publishroomid
    ), 1);

注意更改:

  • 没有 CTE,只是使用 SELECT 查询进行变量赋值
  • 使用MAX()聚合函数而不是 ORDER BY + LIMIT
  • 结束了COALESCE(x,1)函数正确插入房间的第一个联系人,它将返回 1如果您的查询确实返回 NULL

您的触发器应如下所示

CREATE OR REPLACE FUNCTION publishroomcontactorder() RETURNS trigger AS $publishroomcontacts$
BEGIN   
  IF (TG_OP = 'INSERT') THEN
    NEW.contactorder = COALESCE((
      SELECT max(contactorder) + 1
      FROM publishroomcontacts
      WHERE publishroomid = NEW.publishroomid
      ), 1);
  END IF;
  RETURN NEW;
END;
$publishroomcontacts$ LANGUAGE plpgsql;

Postgres 会自行插入行,您无需执行任何操作,因为 RETURN NEW这样做。

此解决方案不考虑并发插入,这使得多用户环境不安全!您可以通过执行 UPSERT 来解决此问题!

关于Postgresql 触发器语法错误位于 "NEW"处或附近,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51837000/

相关文章:

vba - 从 Excel VBA 到 PostgreSQL 数据库的连接缓慢

postgresql - 多种订购选项

sql - 如何在 PostgreSQL 查询中对不同的元组进行排序

java - 如何通过加入来持久化实体?

ruby-on-rails - 搜索给定不同货币价格范围的型号

sql - 优化 postgres 中的大 "distinct"选择

python - Alembic 迁移卡在 postgresql 上?

Python - Psycopg2,如何在 cur.execute() 中混合元组和字符串?

postgresql - Postgres 对一个非常简单的 SELECT x ... ORDER BY x 进行 Seq Scan 而不是 Index Only Scan

javascript - 无法访问本地 postgreSQL heroku、node.js