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.
Thats correct you can not update the same table where the trigger is getting executed, however if you use before update
you can set the st
to 0 by checking the conditions something as
DELIMITER $$
USE `smsdev`$$
DROP TRIGGER /*!50032 IF EXISTS */ `pageprivilege_update`$$
CREATE
/*!50017 DEFINER = 'smsdev'@'%' */
TRIGGER `pageprivilege_update` BEFORE UPDATE ON `pageprivilege`
FOR EACH ROW
BEGIN
if (new.ad = 0 AND new.ed =0 AND new.dl =0 AND new.rd = 0) then
set new.st=0 ;
end if;
END;
$$
DELIMITER ;
Best Answer
Assuming this is a PL/pgSQL function, then - as documented in the manual - a trigger function automatically has access to some special variables. One of them is
TG_OP
that identifies the trigger operation.The manual even has an example on how to use it: