【发布时间】:2012-11-25 19:10:51
【问题描述】:
我正在尝试在 PostgreSQL 中创建一个触发器函数,该函数应在插入或更新记录之前检查具有相同 id 的记录(即通过 id 与现有记录进行比较)。如果函数找到具有相同id 的记录,则该条目设置为time_dead。让我用这个例子来解释:
INSERT INTO persons (id, time_create, time_dead, name)
VALUES (1, 'now();', ' ', 'james');
我想要一张这样的桌子:
id time_create time-dead name
1 06:12 henry
2 07:12 muka
id 1 有一个 time_create 06.12,但 time_dead 是 NULL。这与id 2 相同,但下次我尝试使用相同的 id 但不同的名称运行insert 查询时,我应该得到一个这样的表:
id time_create time-dead name
1 06:12 14:35 henry
2 07:12 muka
1 14:35 waks
henry 和 waks 共享相同的 id 1。运行insert 查询后,henry 的time_dead 等于waks 的time_create。如果要使用 id 1 创建另一个条目,比如说 james,james 的时间条目将等于 waks 的 time_dead。以此类推。
到目前为止,我的功能看起来像这样。但它不起作用:
CREATE FUNCTION tr_function() RETURNS trigger AS '
BEGIN
IF tg_op = ''UPDATE'' THEN
UPDATE persons
SET time_dead = NEW.time_create
Where
id = NEW.id
AND time_dead IS NULL
;
END IF;
RETURN new;
END
' LANGUAGE plpgsql;
CREATE TRIGGER sofgr BEFORE INSERT OR UPDATE
ON persons FOR each ROW
EXECUTE PROCEDURE tr_function();
当我运行它时,它说time_dead 不应该是null。有没有办法我可以编写一个trigger function,它会在inserting or updating 上自动输入时间,但是当我运行select 查询时会给我上表一样的结果?
我做错了什么?
我的两张桌子:
CREATE TABLE temporary_object
(
id integer NOT NULL,
time_create timestamp without time zone NOT NULL,
time_dead timestamp without time zone,
PRIMARY KEY (id, time_create)
);
CREATE TABLE persons
(
name text
)
INHERITS (temporary_object);
【问题讨论】:
-
第一个问题是您不能更新在更新同一个表时触发的触发器内的表。这将导致无限递归。
-
可以包含表的定义吗?
-
@IgorRomanchenko 等一下
-
@DanielVérité:你当然可以这样做。但是,防止无限递归是您的责任。我添加了一个子句来防止这种情况..
-
我清理了问题并修复了您设置中的矛盾,以使示例正常工作。
标签: postgresql triggers timestamp infinite-loop plpgsql