Sql 触发器检查表中某行中的某些值是否相等,若不相等则更新,然后插入

Sql 触发器检查表中某行中的某些值是否相等,若不相等则更新,然后插入,sql,postgresql,triggers,Sql,Postgresql,Triggers,我在psql中的触发器有问题,它需要检查表中是否已经存在一些值(发送者、接收者、主题),如果它们存在,我只需要更新该行中的一个值(主题=RE:+subject),否则我需要插入新行 CREATE OR REPLACE FUNCTION check_theme() RETURNS TRIGGER AS $$ DECLARE e BOOLEAN; BEGIN e := EXISTS( SELECT * FROM mess

我在psql中的触发器有问题,它需要检查表中是否已经存在一些值(发送者、接收者、主题),如果它们存在,我只需要更新该行中的一个值(主题=RE:+subject),否则我需要插入新行

CREATE OR REPLACE FUNCTION check_theme()
RETURNS TRIGGER
AS $$
    DECLARE e BOOLEAN;
    BEGIN
        e := EXISTS(
            SELECT *
            FROM message
            WHERE sender = NEW.sender
              AND reciever = NEW.reciever
              AND subject = NEW.subject
            );
        IF NOT e THEN
            INSERT INTO message(sender, reciever, subject, text)
            VALUES(NEW.sender, NEW.reciever, NEW.subject, NEW.text);
        ELSE
            UPDATE message
            SET subject = 'Re: ' || NEW.subject
            WHERE sender = NEW.sender
              AND reciever = NEW.reciever
              AND subject = NEW.subject;
        END IF;
        RETURN NEW;

    END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER theme_check
BEFORE INSERT OR UPDATE
ON message
FOR EACH ROW EXECUTE PROCEDURE check_theme(); 
所以,在我想插入新行之后,它已经具有相同的发送方值,接收方和主题触发器进入不定式循环


我做错了什么?

几天后,我发现我对触发器工作原理的了解是错误的。。所以我的错误是,我添加了插入函数,但如果没有相同发件人、收件人和标题的邮件,插入操作无论如何都会完成。这就是为什么我总是得到不定式循环。 因此,将要工作的代码是belove

CREATE OR REPLACE FUNCTION provjera_teme()
RETURNS TRIGGER
AS $$
    DECLARE postoji BOOLEAN;
    BEGIN
        postoji := EXISTS(
            SELECT poruka
            FROM poruka
            WHERE posiljatelj = NEW.posiljatelj
              AND primatelj = NEW.primatelj
              AND (naslov = NEW.naslov OR naslov LIKE 'Re: ' || NEW.naslov)
            );    
        IF postoji THEN
            UPDATE poruka
            SET naslov = 'Re: ' || naslov
            WHERE posiljatelj = NEW.posiljatelj
                  AND primatelj = NEW.primatelj
                  AND naslov = NEW.naslov AND naslov NOT LIKE 'Re%';
                RETURN NULL;
        END IF;
        RETURN NEW;
    END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER tema_provjera
BEFORE INSERT
ON poruka
FOR EACH ROW EXECUTE PROCEDURE provjera_teme(); 

几天后,我发现我对触发器工作原理的了解是错误的。。所以我的错误是,我添加了插入函数,但如果没有相同发件人、收件人和标题的邮件,插入操作无论如何都会完成。这就是为什么我总是得到不定式循环。 因此,将要工作的代码是belove

CREATE OR REPLACE FUNCTION provjera_teme()
RETURNS TRIGGER
AS $$
    DECLARE postoji BOOLEAN;
    BEGIN
        postoji := EXISTS(
            SELECT poruka
            FROM poruka
            WHERE posiljatelj = NEW.posiljatelj
              AND primatelj = NEW.primatelj
              AND (naslov = NEW.naslov OR naslov LIKE 'Re: ' || NEW.naslov)
            );    
        IF postoji THEN
            UPDATE poruka
            SET naslov = 'Re: ' || naslov
            WHERE posiljatelj = NEW.posiljatelj
                  AND primatelj = NEW.primatelj
                  AND naslov = NEW.naslov AND naslov NOT LIKE 'Re%';
                RETURN NULL;
        END IF;
        RETURN NEW;
    END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER tema_provjera
BEFORE INSERT
ON poruka
FOR EACH ROW EXECUTE PROCEDURE provjera_teme(); 

INSERT之前的
触发器应该只说
如果e那么NEW.subject='Re:'| | NEW.subject。我不确定更新后的
案例中您想要什么,不过。。。您真的希望更新触发表中的新插入吗?更清楚地说,我需要解决这个问题:实现触发器和触发器适当的函数“check_theme”,该函数将检查邮件表中的每个条目是否已经有来自同一发件人、收件人和具有相同标题的邮件。如果有,则将标题更改为包含前缀“Re:”示例:“Hello”的标题将更改为“Re:Hello”,如果已经存在此类主题。如果没有,则需要插入新消息。插入之前的
触发器应该只说
如果e then new.subject='Re:'| | new.subject。我不确定更新后的
案例中您想要什么,不过。。。您真的希望更新触发表中的新插入吗?更清楚地说,我需要解决这个问题:实现触发器和触发器适当的函数“check_theme”,该函数将检查邮件表中的每个条目是否已经有来自同一发件人、收件人和具有相同标题的邮件。如果有,则将标题更改为包含前缀“Re:”示例:“Hello”的标题将更改为“Re:Hello”,如果已经存在此类主题。如果没有,则需要插入新消息。