Trigger, initcap a value before a insert (PostgreSQL) - postgresql

I know that there is an initcap () function, which will perform a transformation for a 'string'. But I want to know how I can perform a trigger that executes this function before inserting a value in the column name into my table client. In other words how my function 'func ()' needs to be declared.
CREATE TRIGGER trigg
BEFORE INSERT
ON client
FOR EACH ROW
EXECUTE PROCEDURE func()
CREATE FUNCTION func()
returns trigger as
$BODY$
begin
**???**
end;
$BODY$ language plpgsql;

You can access the record before the change that triggered the trigger via the OLD pseudo record and after the change via the NEW pseudo record in your trigger function. You can also change the latter.
So to change the name of your client use
NEW.name := initcap(NEW.name);
RETURN NEW;
in your trigger function body.
For more information see 42.9. Trigger Procedures.

Related

Pass the query result to the function

I created a function that takes as a parameter a string by which i am looking for the desired element in the Bus table. After that i create a trigger that will fire after inserting into the Maintenance table. Here i have a problem: i specify that when changing the table, call the function and pass the last added element there, but the trigger is not created.
I looked for similar questions and saw that you need to take the query in brackets, but it did not help.
Ask for your help!
Function:
create function set_status(model_ varchar(50)) returns void as $$
update Bus set technical_condition = 'don`t work' where model = model_;
$$ LANGUAGE sql;
Trigger:
create trigger check_insert
after insert on Maintenance
for each row
execute procedure set_status((select model from Maintenance order by id_m desc limit 1));
First off your trigger function must be of the form:
create or replace function <function_name>()
returns trigger
language plpgsql
as $$
begin
...
end;
$$;
The language specification may come either before the code or after it. Moreover it must be defined returning trigger and as taking no parameters. See documentation.
You can achieve what you want by moving the select status ... query into the trigger function itself.
create or replace function set_status()
returns trigger
language plpgsql
as $$
begin
update bus
set technical_condition =
(select model
from maintenance
order by id_m desc
limit 1
) ;
return null;
end;
$$;
create trigger check_insert
after insert on maintenance
for each row
execute procedure set_status();
NOTE: Not Tested.

How to return a JSON in a trigger function in PostgreSQL?

I need that when inserting data into a table, a trigger function returns a JSON. But, from what I saw, a trigger function can only return a trigger. What alternatives are there for what I want to do?
-- Trigger Function
CREATE OR REPLACE FUNCTION fn_save_gps_data()
RETURNS json
LANGUAGE 'plpgsql'
AS
$$
DECLARE "gpsData" json;
BEGIN
-- PERFORM fn_return_gps_data();
SELECT json_agg(row_to_json(gps)) FROM tbl_admon_gps_data gps INTO "gpsData";
RETURN "gpsData";
END;
$$;
------------------------------------------------------------------------------
-- Trigger that executes the previous Function
CREATE TRIGGER trg_save_gps_data AFTER INSERT ON tbl_admon_gps_data
FOR EACH ROW
EXECUTE PROCEDURE fn_save_gps_data();
The value returned by an AFTER trigger is ignored. The trigger is only useful for its side effects.

Syntax error while creating a trigger in PostgreSQL

I created a table name Student in PostgreSQL and then I tried defining a trigger on that table but it's showing an error message in doing so.
Trigger Syntax:
CREATE TRIGGER bi_Student BEFORE INSERT ON Student as $$
FOR EACH ROW
BEGIN
raise notice 'Successfully inserted into table(%)', user;
end $$;
Table Creation Command:
create table Student(Stu_id int, Stu_Name text, Stu_Age int, Stu_address char(30));
Actually I tried to declare the execution statements directly inside the trigger only rather than calling any procedure/ function from the trigger which is working fine but I want to do in this way in PostgreSQL.
PostgreSQL doesn't support it. You need trigger function always.
As documented in the manual you need a trigger function
create function my_trigger_function()
returns trigger
as
$$
begin
raise notice 'Successfully inserted into table(%)', user;
return new; --<< important (see the manual for details)
end
$$
language plpgsql;
Not sure what you intend with the user parameter there, as that is not the table name, but the current database user. If you want to display the actual table name, you need to use TG_RELNAME instead - which is an implicit variable available in the trigger function.
And a trigger definition
CREATE TRIGGER bi_Student
BEFORE INSERT ON Student
FOR EACH ROW
execute function my_trigger_function();

PostgreSQL Trigger Error : control reached end of trigger procedure without RETURN

I am trying to create a trigger on a column of my table like this in Postgresql 9.5:
CREATE OR REPLACE FUNCTION app.combo_min_stock()
RETURNS TRIGGER AS
$combo_sync$
DECLARE combo_product_ids INTEGER[] := array(SELECT combo_product_map.combo_productid FROM app.combo_product_map WHERE combo_product_map.productid=NEW.productid);
DECLARE comboid INTEGER;
BEGIN
-- UPDATE MINIMUM STOCK FOR COMBO SKUS --
FOREACH comboid IN ARRAY combo_product_ids
LOOP
UPDATE app.inventory SET
good_stock = combo_data.min_good_stock,
bad_stock = combo_data.min_bad_stock,
to_be_updated = true
FROM
(SELECT
product.productid,
MIN(inventory.good_stock) as min_good_stock,
MIN(inventory.bad_stock) as min_bad_stock
FROM
app.product,
app.inventory,
app.combo_product_map
WHERE
product.is_combo=true AND
product.productid=comboid AND
product.productid=combo_product_map.combo_productid AND
combo_product_map.productid=inventory.productid
GROUP BY
product.productid) AS combo_data
WHERE
combo_data.productid=inventory.productid;
END LOOP;
END;
$combo_sync$
LANGUAGE plpgsql;
ALTER FUNCTION app.combo_min_stock()
OWNER TO postgres;
CREATE TRIGGER combo_sync
AFTER UPDATE OF good_stock
ON app.inventory
FOR EACH ROW
EXECUTE PROCEDURE app.combo_min_stock();
When I try to edit a value for good_stock column in my inventory table, it is throwing me this error:
An error has occurred:
ERROR: control reached end of trigger procedure without RETURN
CONTEXT: PL/pgSQL function app.combo_min_stock()
What is wrong with this query?
Try using this:
END LOOP;
RETURN NULL;
According to CREATE TRIGGER docs
function_name
A user-supplied function that is declared as taking no arguments and
returning type trigger, which is executed when the trigger fires.
In the syntax of CREATE TRIGGER, the keywords FUNCTION and
PROCEDURE are equivalent, but the referenced function must in any
case be a function, not a procedure. The use of the keyword
PROCEDURE here is historical and deprecated.
What is trigger function?
Function which returns a trigger. ex:
CREATE FUNCTION do_something() RETURNS trigger
Important bit is trigger function should be function not a procedure
Difference between Procedures and Functions according to docs
A procedure is a database object similar to a function. The key
differences are:
Procedures are defined with the CREATE PROCEDURE command, not CREATE
FUNCTION.
Procedures do not return a function value; hence CREATE PROCEDURE
lacks a RETURNS clause. However, procedures can instead return data to
their callers via output parameters.
While a function is called as part of a query or DML command, a
procedure is called in isolation using the CALL command.
A procedure can commit or roll back transactions during its execution
(then automatically beginning a new transaction), so long as the
invoking CALL command is not part of an explicit transaction block. A
function cannot do that.
Certain function attributes, such as strictness, don't apply to
procedures. Those attributes control how the function is used in a
query, which isn't relevant to procedures.
Simply put functions should have a return statement
So each and every trigger function need to have a return statement. Some possible return statements for trigger functions.
RETURN NULL;
RETURN OLD;
RETURN NEW;

How I can "atomically" replace function that is executed by trigger?

Here is code I have used to create FUNCTION and TRIGGER.
CREATE OR REPLACE FUNCTION inc_post_loves() RETURNS TRIGGER AS
$BODY$
BEGIN;
...
END;
$BODY$
language plpgsql;
CREATE TRIGGER on_post_love_create
AFTER INSERT ON "PostLoves"
FOR EACH ROW EXECUTE PROCEDURE inc_post_loves()
Now I would like to modify FUNCTION inc_post_loves().
If I will execute CREATE OR REPLACE FUNCTION inc_post_loves()... again, do I have guarantee that previously created trigger won't be deleted (like cascade) and it wont fail during replacing function?