I am trying to call a function inside of a trigger in postgres. Basically I have a function,

c.check_level(bigint, integer)
which returns a boolean value.

I would like to call this function inside of a trigger as follows:

CREATE OR REPLACE FUNCTION c.check_level_tg()
RETURNS trigger AS
$BODY$
DECLARE
    parent_id  int8;
    level int;
    result bool;
begin
    parent_id := NEW.fk_parent;
    level := NEW.level;

    select * from c.check_category_level(parent_id, level) as result;

    if (result) then
        return (NEW);
    else 
        return(NULL);
    end if;

END; 
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION c.check_category_level_tg()
  OWNER TO postgres;

When I try to put data in the table on which this trigger resides, I get an error: "ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function".

The function c.check_level works properly when run in isolation.

  • select c.check_category_level(parent_id, level) INTO result; – joop Dec 3 '13 at 12:55
  • Thanks! it works! Do you want to add it as an answer? – Christopher Rapcewicz Dec 3 '13 at 13:03
  • Maybe. BTW: I don't think it is a very good idea to hide the logic inside a function (function call overhead will be rather large) Besides, I expect the (recursive?) query inside the function to be related to the table for which the trigger is fired) – joop Dec 3 '13 at 13:11
  • I have some complex data integrity rules which I need to apply to several tables. It is true that I hide the logic, but in return I only have to write the code once. I am not concerned about the speed because I will be doing far more reads on the tables than writes. – Christopher Rapcewicz Dec 3 '13 at 13:23
  • I understand you do not want to duplicate the code. And complex constraints sometimes require complex solutions. (in your case: limiting the nesting depth?) Have you considered using a canary-field (or table), maintained by a trigger function, but with a simple CHECK constraint on it? – joop Dec 3 '13 at 13:27
up vote 3 down vote accepted

Change

select * from c.check_category_level(parent_id, level) as result;

into:

SELECT c.check_category_level(parent_id, level) INTO result;

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.