简体   繁体   English

Postgres语法错误-触发器

[英]Postgres Syntax Error - Triggers

I am using Triggers, cases and Exists for the first time, and cannot figure out the problem. 我第一次使用触发器,案例和存在,但无法找出问题所在。 I have replaced the table names are attributes for the responder's convenience. 我已将表名替换为响应者方便的属性。

Essentially, what I want is that: When I insert an entry to my temporal table, 本质上,我想要的是:当我在时态表中插入一个条目时,

  • if the new entry's primary key already exists in the temporal table, I want this new entry's start date to be the previous record's end date. 如果新条目的主键已经存在于临时表中,则我希望此新条目的开始日期为上一条记录的结束日期。

  • if the new entry is completely new to the table, nothing happens (the insert operates as usual). 如果新条目对表来说是全新的,则什么也不会发生(插入操作照常进行)。

The code is: 代码是:

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

You have a conceptual error with regards to the use of the CASE clause in a SELECT statement: you evaluate some condition to produce an output for the select list. 关于在SELECT语句中使用CASE子句,您在概念上存在错误:您评估一些条件以产生选择列表的输出。 Instead you use it as a logic branch operation as you would in a procedural language like C . 相反,您可以像使用C这样的过程语言一样,将其用作逻辑分支操作。 Since a trigger is always written in the plpgsql procedural language you can easily rewrite the trigger function as follows: 由于触发器始终以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;

The PERFORM command checks if some data is present without returning any data and sets the FOUND implicit variable to true or false which you can then check. PERFORM命令检查是否存在某些数据而不返回任何数据,并将FOUND隐式变量设置为truefalse ,然后可以进行检查。

But if this is all the logic in your trigger function (ie there are no parts which you do not show here) you can simply leave out the check and do a straight UPDATE : if a record is not there for updating then nothing happens and the trigger function simply continues: 但是,如果这是触发函数中的全部逻辑(即,没有在此处未显示的部分),您可以简单地省略检查并直接执行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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM