You can do something along the following lines:
test=> CREATE OR REPLACE FUNCTION temptabl(cnt integer)
RETURNS SETOF integer AS
$body$
BEGIN
CREATE TEMPORARY TABLE tmp_container ON COMMIT DROP AS
SELECT a
FROM generate_series(1, cnt) t(a);
IF (SELECT count(1) FROM tmp_container) > 5
THEN
RETURN QUERY SELECT a FROM tmp_container;
END IF;
END;
$body$
LANGUAGE plpgsql;
test=> SELECT * FROM temptabl(4);
temptabl
----------
(0 rows)
test=> SELECT * FROM temptabl(6);
temptabl
----------
1
2
3
4
5
6
(6 rows)
This way you have to perform your original query only once. All other statements work on the temporary table.
There are several things wrong with this trigger.
First: your delete statement. You can't compare NULL
using =
. You need to use IS NULL
:
DELETE FROM test2 WHERE email IS NULL;
Second: a trigger function (quote from the manual) "must return either NULL or a record/row value having exactly the structure of the table the trigger was fired for."
So return test2;
should be return new;
.
Third: you created a row level trigger, which is going to be very bad for performance. As you are not dependent on the actual values that are changed by the update, a statement level trigger will be much more efficient, because it only fires once for each UPDATE
statement rather than once for each row that has been changed.
In a statement level trigger the return value is ignored, so the suggested return new;
from above becomes a return null;
as there is no new
or old
record available in a statement level trigger.
Putting it all together:
CREATE OR REPLACE FUNCTION clean_emp()
RETURNS trigger AS $$
BEGIN
DELETE FROM test2 WHERE email IS NULL;
return NULL; -- as we are now using a statement level trigger, null is fine
END;
$$
LANGUAGE plpgsql VOLATILE;
CREATE TRIGGER trig_empty2
AFTER UPDATE OF name ON test2
FOR EACH STATEMENT --<< fire only once for each statement, not row
EXECUTE PROCEDURE clean_emp();
If you also want to disallow empty values ( ''
is something different than 'NULL') you would need to change the condition to where coalesce(email, '') = '')
But the trigger approach is wrong to begin with: you should declare the email
column as NOT NULL
and then nobody will ever be able to put NULL
values into that column and therefore you don't need the trigger at all.
Best Answer