【发布时间】:2018-03-08 00:08:40
【问题描述】:
我正在制作一个函数触发器,该触发器将在某个表中插入新记录之前执行,此函数触发器将在另一个表中插入新记录,其中包含第一次插入的某些值。我需要在插入之前执行,因为我需要将第一个表中的最后一条记录与新记录的某些字段进行比较。
这里的问题是,我可以找到如何获取将要插入的记录的 ID,因为该记录还不存在。
我正在考虑用户一个序列来获取将要生成的下一个 id,但我不知道如果有多个用户同时写入数据库,这些是否会导致问题。
这是我的函数 PostgreSQL 函数:
CREATE FUNCTION mydb.mytriggername()
RETURNS trigger
LANGUAGE 'plpgsql'
COST 100.0
VOLATILE NOT LEAKPROOF
AS $BODY$
BEGIN
IF (
SELECT tvalue FROM mydb.myTable WHERE type = NEW.type AND sb = NEW.sb AND st= NEW.st order by id DESC LIMIT 1
) <> NEW.tvalue THEN
INSERT INTO mydb.anotherTable( type, date, desc, tp, sb, st, ref)
SELECT 'tc', NEW.date, 'newdesc', NEW.type, NEW.sb, NEW.st, CONCAT('{"id_ref":', NEW.id, '}');
END IF;
RETURN NEW;
END;
请注意,我需要在 CONCAT('{"id_ref":', NEW.id, '}'); 上使用它,但正如我之前所说,我没有 id,因为它还没有插入新记录。
你有什么办法可以解决我的问题吗?
【问题讨论】:
-
查看表是否使用串行字段,在这种情况下,您有一个序列并且可以获得下一个值。如果没有,您可以尝试使用 max(id)
-
是的@Adam,这个字段正在使用序列号,我担心的是如果在第一个事务开始的同一秒内有另一个事务会发生什么。交易是否有可能保存第三条记录的id而不是当前交易?
-
@Adm,看起来效果很好,但是当查询返回空结果集时,比较不起作用“空结果集 NEW.tvalue”
-
@Adam,实际上这种方法存在一个问题,当您执行 nextval 时,它会获取下一个 id 并将值保存在序列上。所以当触发器再次执行 nextval 并且返回的 id 已经不一样了。
标签: database postgresql triggers