Postgres语法错误 - 触发器

时间:2016-10-17 23:56:17

标签: sql postgresql triggers

我第一次使用触发器,案例和存在,并且无法弄清楚问题。我已经替换了表名是响应者方便的属性。

基本上,我想要的是:当我在临时表中插入一个条目时,

  • 如果新条目的主键已经存在于时态表中,我希望这个新条目的开始日期是前一条记录的结束日期。

  • 如果新条目对表格来说是全新的,则没有任何反应(插入操作正常)。

代码是:

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(); 

1 个答案:

答案 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隐式变量设置为truefalse,然后您可以检查。

但如果这是触发器功能中的所有逻辑(即没有你没有在这里显示的部分),你可以简单地省略检查并直接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;