我第一次使用触发器,案例和存在,并且无法弄清楚问题。我已经替换了表名是响应者方便的属性。
基本上,我想要的是:当我在临时表中插入一个条目时,
如果新条目的主键已经存在于时态表中,我希望这个新条目的开始日期是前一条记录的结束日期。
如果新条目对表格来说是全新的,则没有任何反应(插入操作正常)。
代码是:
CREATE OR REPLACE FUNCTION update_End_Date()
RETURNS trigger AS
$$
BEGIN
SELECT CASE
WHEN EXISTS ( SELECT TemporalTable.primaryKey FROM TemporalTable WHERE primaryKey = NEW.primaryKey )
THEN
UPDATE
TemporalTable
SET
TemporalTable.DtEnd = NEW.DtStart
WHERE
TemporalTable.PrimaryKey = NEW.PrimaryKey AND
TemporalTable.DtEnd IS NULL
;
END
RETURN NEW;
RETURN NEW;
END;
$$
LANGUAGE 'plpgsql';
CREATE TRIGGER update_End_Date
BEFORE INSERT
ON Table1
FOR EACH ROW
EXECUTE PROCEDURE update_End_Date();
答案 0 :(得分:0)
在CASE
语句中使用SELECT
子句时存在概念错误:您评估某些条件以生成选择列表的输出。相反,您将其用作逻辑分支操作,就像在C
这样的过程语言中一样。由于触发器始终以plpgsql
过程语言编写,因此您可以轻松地重写触发器函数,如下所示:
CREATE OR REPLACE FUNCTION update_End_Date() RETURNS trigger AS $$
BEGIN
PERFORM * FROM TemporalTable WHERE primaryKey = NEW.primaryKey;
IF FOUND THEN
UPDATE TemporalTable
SET DtEnd = NEW.DtStart
WHERE PrimaryKey = NEW.PrimaryKey AND DtEnd IS NULL;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
PERFORM
命令检查是否存在某些数据而不返回任何数据,并将FOUND
隐式变量设置为true
或false
,然后您可以检查。
但如果这是触发器功能中的所有逻辑(即没有你没有在这里显示的部分),你可以简单地省略检查并直接UPDATE
:如果记录不在那里为了更新然后没有任何反应,触发功能只是继续:
CREATE OR REPLACE FUNCTION update_End_Date() RETURNS trigger AS $$
BEGIN
UPDATE TemporalTable
SET DtEnd = NEW.DtStart
WHERE PrimaryKey = NEW.PrimaryKey AND DtEnd IS NULL;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;