2011-02-01 19 views
14

私が持っている:PostgreSQLのトリガ誤差

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 

それはOLDまたはNEWが何であるかを知っていないように思え。どうすれば修正できますか?

答えて

18

あなたはOK、多分私はカウントする必要はありませんFOR EACH ROW

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

ああ、それはとても明白です....ありがとう:) –

12

deleteの場合、トリガーだけがOLDレコードが定義され、NEWが未定義です。コード内で、トリガーがDELETEまたはINSERT(変数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" 
EXECUTE PROCEDURE aktualizujIloscPodan(); 
+0

を使用する必要があります...変更私のコードと別のエラーがあります。手伝ってくれますか? 2つのこと:NULLを返すことはできません(返さずに動作します)。ELIFではなくELIFです –

+0

@Miko申し訳ありませんが、私はそれをチェックしませんでした。編集されました。 –

+0

@Miko afterトリガーは戻り値を必要としません。 –