【问题标题】:PostgreSQL Trigger errorPostgreSQL 触发错误
【发布时间】:2026-01-29 05:45:01
【问题描述】:

我有:

CREATE OR REPLACE FUNCTION aktualizujIloscPodan() RETURNS TRIGGER AS
$BODY$ 
  DECLARE 
    n integer;
    sid integer;
BEGIN

sid=0;
IF (TG_OP='INSERT') THEN
sid = NEW."studentID";
ELSIF (TG_OP='DELETE') THEN
sid = OLD."studentID";
END IF;

n = COALESCE ((SELECT count("studentID") as c
FROM "Podania" WHERE "studentID"=sid
GROUP BY "studentID"), 0);

UPDATE "Studenci" SET "licznikpodan" = n WHERE "ID"=sid;
END;
$BODY$ 
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS triggenPodan ON "Podania";

CREATE TRIGGER triggenPodan AFTER INSERT OR DELETE
ON "Podania"
EXECUTE PROCEDURE aktualizujIloscPodan();

当我尝试执行时:

DELETE FROM "Podania"

I get

ERROR:  record "old" is not assigned yet
DETAIL:  The tuple structure of a not-yet-assigned record is indeterminate.
CONTEXT:  PL/pgSQL function "aktualizujiloscpodan" line 11 at assignment

********** Błąd **********

ERROR: record "old" is not assigned yet
Stan SQL:55000
Szczegóły:The tuple structure of a not-yet-assigned record is indeterminate.
Kontekst:PL/pgSQL function "aktualizujiloscpodan" line 11 at assignment

它似乎不知道OLDNEW 是什么。我该如何解决?

【问题讨论】:

    标签: postgresql triggers


    【解决方案1】:

    对于delete 触发器,仅定义了OLD 记录并且未定义NEW。因此,在代码中,检查触发器是否以DELETEINSERT(变量TG_OP)运行并访问相应的记录。

    另外,这里根本不用数就可以去,像这样:

    CREATE OR REPLACE FUNCTION aktualizujIloscPodan() RETURNS TRIGGER AS
    $BODY$ 
    DECLARE 
        n integer;
    BEGIN
        IF TG_OP = 'INSERT' then
           UPDATE "Studenci" SET "ilosc_podan" = "ilosc_podan" + 1 WHERE "ID"=NEW."studentID";
        ELSIF TG_OP = 'DELETE' then
           UPDATE "Studenci" SET "ilosc_podan" = "ilosc_podan" - 1 WHERE "ID"=OLD."studentID";
    
        END IF;
    END;
    
    $BODY$ 
    LANGUAGE plpgsql;
    
    DROP TRIGGER IF EXISTS triggenPodan ON "Podania";
    
    CREATE TRIGGER triggenPodan AFTER INSERT OR DELETE
    ON "Podania" FOR EACH ROW
    EXECUTE PROCEDURE aktualizujIloscPodan();
    

    【讨论】:

    • 好的,也许我不需要数... 修改了我的代码,又得到了一个错误。你能帮我吗?两件事:它不允许返回 NULL(不返回工作),它是 ELSIF 而不是 ELIF
    • @Miko 抱歉,我没有检查它。已编辑。
    • @Miko after triggers 不需要返回值。
    • 哦,我明白了。这是关于这个回归的......但我仍然得到旧未定义的消息?为什么?
    【解决方案2】:

    你需要使用FOR EACH ROW

    CREATE TRIGGER triggerPodan AFTER INSERT OR DELETE
    ON "Podania" FOR EACH ROW
    EXECUTE PROCEDURE aktualizujIloscPodan();
    

    【讨论】: