I try to update a procedure in psql, the code gives no error:
CREATE OR REPLACE FUNCTION public.decrement_user_followers()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
UPDATE users SET unit_followers = unit_followers - 1 WHERE id = OLD.user_id_followed;
UPDATE users SET unit_following = unit_following - 1 WHERE id = OLD.user_id_follower;
RETURN OLD;
END $function$
But when I try to see the change \df+ decrement_user_followers gives me the old code.
Any suggestions?
The ";" was missing at the end ... ahhh
CREATE OR REPLACE FUNCTION public.decrement_user_followers()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
UPDATE users SET unit_followers = unit_followers - 1 WHERE id = OLD.user_id_followed;
UPDATE users SET unit_following = unit_following - 1 WHERE id = OLD.user_id_follower;
RETURN OLD;
END $function$;
Related
This question already has an answer here:
Trigger to update a column on update
(1 answer)
Closed 11 months ago.
everyone!
i want to do a very simple trigger that sees if some conditionals are 0 they set false on the same table, buy i am doing wrong and it s not updating
CREATE or REPLACE FUNCTION chequeo_datos() RETURNS trigger AS $$
BEGIN
IF NEW.val_cuota = 0 or NEW.val_pat = 0 THEN
UPDATE habitat SET status=False;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER chequeo_datos AFTER INSERT OR UPDATE ON public.habitat
FOR EACH ROW EXECUTE FUNCTION chequeo_datos();
it gives me this error : "stack depth limit reached".
could you tell me what i am doing wrong?
Don't UPDATE the table, assign the new value to the record's column:
CREATE or REPLACE FUNCTION chequeo_datos() RETURNS trigger AS $$
BEGIN
IF NEW.val_cuota = 0 or NEW.val_pat = 0 THEN
new.status := False;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
For that to work, you need a BEFORE trigger:
CREATE TRIGGER chequeo_datos
BEFORE INSERT OR UPDATE ON public.habitat
FOR EACH ROW EXECUTE FUNCTION chequeo_datos()
I'm trying to mark a boolean column on a different table to true upon the insertion of a matching record.
Here's what I've got:
CREATE or replace FUNCTION mark_as_sold() RETURNS trigger AS
$BODY$
BEGIN
UPDATE listing
set listing.sold = true;
WHERE listing.id = NEW.listing_id;
RETURN NEW;
END
$BODY$
LANGUAGE plpgsql;
CREATE TRIGGER update_child_after_update
AFTER INSERT
ON transaction
FOR EACH ROW
EXECUTE PROCEDURE mark_as_sold();
When I create a record on the transaction table, nothing happens. I'm stumped. Any help is greatly appreciated.
I figured it out. I was messing up my relations. Here's the proper code:
CREATE OR REPLACE FUNCTION mark_as_sold()
RETURNS TRIGGER
AS $$
BEGIN
UPDATE listing
set sold = true
WHERE listing.id = NEW.listing_id;
RETURN NEW;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER test_trigger BEFORE INSERT OR UPDATE
ON "transaction"
FOR EACH ROW EXECUTE PROCEDURE mark_as_sold();
I created a trigger fk_pay_trigger on INSERT
CREATE TRIGGER fk_pay_trigger
BEFORE INSERT ON fk_payment_temp
FOR EACH ROW
EXECUTE PROCEDURE add_insert_trigger_fk()
and function attach is:
-- Function: add_insert_trigger_fk()
-- DROP FUNCTION add_insert_trigger_fk();
CREATE OR REPLACE FUNCTION add_insert_trigger_fk()
RETURNS trigger AS
$BODY$
Declare
begin
if (TG_TABLE_NAME = 'fk_payment_temp') then
if (TG_OP = 'INSERT') then
Insert into fk_payment_temp_backup values(now(),NEW.settlement_ref_no, NEW.order_type, NEW.fulfilment_type, NEW.seller_sku, NEW.wsn,
NEW.order_id, NEW.order_item_id, NEW.order_date, NEW.dispatch_date, NEW.delivery_date,
NEW.cancellation_date, NEW.settlement_date, NEW.order_status, NEW.quantity, NEW.order_item_value,
NEW.sale_transaction_amount, NEW.discount_transaction_amount, NEW.refund,
NEW.protection_fund, NEW.total_marketplace_fee, NEW.service_tax, NEW.settlement_value,
NEW.commission_rate, NEW.commission, NEW.payment_rate, NEW.payment_fee, NEW.fee_discount,
NEW.cancellation_fee, NEW.fixed_fee, NEW.emi_fee, NEW.total_weight, NEW.shipping_fee,
NEW.reverse_shipping_fee, NEW.shipping_zone, NEW.token_of_apology, NEW.pick_and_pack_fee,
NEW.storage_fee, NEW.removal_fee, NEW.invoice_id, NEW.invoice_date, NEW.invoice_amount,
NEW.sub_category, NEW.total_offer_amount, NEW.my_offer_share, NEW.flipkart_offer_share);
return NEW;
END if;
End if ;
return null;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
Its working fine. but the problem is :
when trigger perform . PG admin Shut down automatically .
I dont know what happen . Is there is any problem in my code or any problem ?
I need help with my trigger. For example i have Query like this
INSERT INTO test(id_users,id_type,id_color) VALUES(1,3,4);
in my data base i have table with name: test
ghost, id, id_users, id_type, id_color
and i need before insert or update to check
Create trigger
Begin
select id from test where ghost = false and id_users = 26 and id_type = 3
if NO execute INSERT
if YEST exit with no action
END
How can i creat this trigger ?
There are two ways, depending on how you want to manage the problem.
If you wish to silence it, use a before trigger and return null:
create function ignore_invalid_row() returns trigger as $$
begin
if not exists(
select 1
from test
where not ghost
and id_users = new.id_users
and id_type = new.id_type
)
then
return null;
end if;
return new;
end;
$$ language plpgsql;
create trigger ignore_invalid_row_tg before insert on test
for each row execute procedure ignore_invalid_row();
If you wish to raise it, use a constraint trigger and raise an exception:
create function reject_invalid_row() returns trigger as $$
begin
if not exists(
select 1
from test
where not ghost
and id_users = new.id_users
and id_type = new.id_type
)
then
raise exception 'message';
end if;
return null;
end;
$$ language plpgsql;
create constraint trigger reject_invalid_row_tg after insert on test
for each row execute procedure reject_invalid_row();
http://www.postgresql.org/docs/current/static/sql-createtrigger.html
First, you need to create a trigger function and then the trigger, based on it:
CREATE OR REPLACE FUNCTION my_trigger_function() RETURNS TRIGGER AS $BODY$ BEGIN
IF EXISTS (SELECT id FROM test WHERE ghost = false AND id_users = 26 AND id_type = 3) THEN
return NEW;
ELSE
return NULL;
END IF; END; $BODY$ LANGUAGE 'plpgsql';
Then, you create trigger based on this function:
CREATE TRIGGER t_my_trigger BEFORE INSERT ON test FOR EACH ROW EXECUTE PROCEDURE my_trigger_function();
For more on triggers, see postgres docs.
I have:
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();
When I try to execute:
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
It seems like it doesn't know what is OLD or NEW. How can I fix that?
You need to use FOR EACH ROW
CREATE TRIGGER triggerPodan AFTER INSERT OR DELETE
ON "Podania" FOR EACH ROW
EXECUTE PROCEDURE aktualizujIloscPodan();
For the delete trigger only OLD record is defined and NEW is undefined. So, in the code, check if the trigger is running as DELETE or INSERT (variable TG_OP) and access the appropriate record.
Besides, you can go without counting here at all, like this:
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();