这就是我想要做的:
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对象进行插入操作?
答案 0 :(得分:2)
我不确定您要做什么,但是这里的语法错误:
with newcontactorder as (SELECT contactorder FROM publishroomcontacts WHERE publishroomid = NEW.publishroomid ORDER BY contactorder limit 1)
NEW.contactorder = (newcontactorder + 1);
如果之后没有选择,请不要使用CTE查询。如果您想在每次添加新contactorder
列时增加publishroomid
列,并且这是您的序列(自动递增)机制,则应将其替换为:
NEW.contactorder = COALESCE((
SELECT max(contactorder)
FROM publishroomcontacts
WHERE publishroomid = NEW.publishroomid
), 1);
请注意更改:
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
!
答案 1 :(得分:1)
WITH
不是PL / pgSQL中的赋值。
PL / pgSQL将该行解释为SQL语句,但这是不好的SQL,因为WITH
子句后面是NEW.contactorder
,而不是SELECT
或另一个CTE。
出现错误;与此无关NEW
。
您可能想要类似的东西
SELECT contactorder INTO newcontactorder
FROM publishroomcontacts
WHERE publishroomid = NEW.publishroomid
ORDER BY contactorder DESC -- you want the biggest one, right?
LIMIT 1;
您必须在newcontactorder
部分中声明DECLARE
。
警告::如果同时存在两个插入,则它们可能会以相同的newcontactorder
结尾。