Postgresql function return affected row count - postgresql

I created a function. I defined returning value void. But I want to show affected row count. How can I do?
CREATE OR REPLACE FUNCTION update() RETURNS void AS
$BODY$
BEGIN
update test_a set name='cde' where name='abc';
update test_b set name='mno' where name='klm';
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update()
OWNER TO postgres;

you should look into GET DIAGNOSTICS, since this is a PLpgSQL function. You might also find the Postgres SQL extension RETURNING * for UPDATE/INSERTS useful.
CREATE OR REPLACE FUNCTION update() RETURNS void AS
$BODY$
DECLARE
a_count integer;
b_count integer;
BEGIN
update test_a set name='cde' where name='abc';
GET DIAGNOSTICS a_count = ROW_COUNT;
update test_b set name='mno' where name='klm';
GET DIAGNOSTICS b_count = ROW_COUNT;
RAISE NOTICE 'The rows affected by A=% and B=%', a_count, b_count ;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update()
OWNER TO postgres;
Depending on what you might want to achieve, the special boolean variable "FOUND" could serve; UPDATE, INSERT, and DELETE statements set FOUND true if at least one row is affected, false if no row is affected.

Related

Postges call procedure for each row of a returning delete statement

I have a delete statement and I want to call a procedure for each of the rows affected by it. Currently I only seem to be able to access a single row of the set that was deleted.
That is if the delete statement below affects multiple rows then I only see a single passed to my analytics procedure
create or replace function platform.update_foo() returns trigger language plpgsql as $$
declare
result record;
begin
with affected_rows as (
delete from private.foo
where environment_id=new.environment_id
and name=new.name
returning *
)
select private.analytics(affected_rows, 'cancelled')
from affected_rows into result;
return new;
end;
$$;
My analytics function has a signature like so
analytics(f private.foo, t varchar default null)
returns void as $$
begin
-- ...

Postgresql function execution error [duplicate]

This question already has an answer here:
PL/PgSQL calling a function inside a loop giving error
(1 answer)
Closed 6 years ago.
I have created two functions. I want to run that functions inside a main function. When I run the main function I get an error. How can I solve this problem?
NOTICE: The rows affected scrap_v15=0
CONTEXT: SQL statement "Select update_scrap_v15()"
PL/pgSQL function all_functions() line 15 at SQL statement
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 all_functions() line 15 at SQL statement
This is my first function
CREATE OR REPLACE FUNCTION update_scrap_v15() RETURNS void AS
$BODY$
DECLARE
scrap_d integer;
BEGIN
update public.scrap_v15_src t2 set scrap = 66 where scrap= 0 and il like '%src%';
GET DIAGNOSTICS scrap_d = ROW_COUNT;
RAISE NOTICE 'The rows affected scrap d=%', scrap_d;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION update_scrap_v15()
OWNER TO postgres;
This is my second function
CREATE OR REPLACE FUNCTION scrap_type() RETURNS void AS
$BODY$
DECLARE
scrap_t integer;
BEGIN
update public.tmz_001 set scrap_type = '55';
update public.tmz_001 set scrap_dtu = '55';
GET DIAGNOSTICS scrap_t = ROW_COUNT;
RAISE NOTICE 'The rows affected scrap d=%', scrap_t;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION scrap_type()
OWNER TO postgres;
This is my main function
CREATE OR REPLACE FUNCTION all_functions() RETURNS void AS
$BODY$
DECLARE
adm_1 integer; adm_2 integer;
BEGIN
Select update_scrap_v15();
GET DIAGNOSTICS adm_1 = ROW_COUNT;
RAISE NOTICE 'affected=%', adm_1;
Select scrap_type();
GET DIAGNOSTICS adm_2 = ROW_COUNT;
RAISE NOTICE 'affected=%', adm_2;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION all_functions()
OWNER TO postgres;
In postgres if function returning void type that invoke by PERFORM.
Instead:
Select update_scrap_v15();
Use that:
PERFORM update_scrap_v15();

Execute update query with IN clause in postgres function

I am trying to create a PostgreSQL function which will update a list of rows. So I want to take a list of text[] as an argument and use the IN clause to execute the query. Also, i want to get the number of rows updated as a returned value.
This worked for me:
CREATE FUNCTION set_mail_isbeingused(list_of_mail_names text[]) RETURNS void AS $$
BEGIN
FOR i in 1 .. array_upper(list_of_mail_names,1)
LOOP
UPDATE mail_isbeingused set isbeingused = 'true' where mailname = list_of_mail_names[i];
END LOOP;
END;
$$
LANGUAGE plpgsql;
But i want to execute it in one update query with IN clause.
CREATE FUNCTION set_mail_isbeingused(list_of_mail_names text[]) RETURNS void AS $$
BEGIN
UPDATE mail_isbeingused set isbeingused = 'true' where mailname in list_of_mail_names;
END;
$$
LANGUAGE plpgsql;
This is what I have been trying to do. Can somebody help me in fixing this?
You need to use the ANY operator with an array. You can't use IN
To obtain the number of rows update, use GET DIAGNOSTICS
CREATE FUNCTION set_mail_isbeingused(list_of_mail_names text[])
RETURNS integer --<< you need to change the return type
AS $$
DECLARE
l_rows integer;
BEGIN
UPDATE mail_isbeingused
set isbeingused = true
where mailname = ANY (list_of_mail_names);
GET DIAGNOSTICS l_rows = ROW_COUNT; --<< get the number of affected rows
RETURN l_rows;
END;
$$
LANGUAGE plpgsql;
Boolean constants don't need to be put into single quotes true is a boolean value 'true' is a string constant.

PostgreSQL increment serial column on update

I am trying to increment a serial column after an update. I have written a trigger function to help.
CREATE FUNCTION "public"."update_transaction_id" () RETURNS trigger AS
$BODY$
DECLARE
curr_id integer;
BEGIN
curr_id = nextval(pg_get_serial_sequence('current_table', 'transaction_id'));
NEW.transaction_id = curr_id;
PERFORM SETVAL((SELECT pg_get_serial_sequence('current_table', 'transaction_id')), curr_id + 1, false);
RETURN NEW;
END;
$BODY$ LANGUAGE 'plpgsql' IMMUTABLE CALLED ON NULL INPUT SECURITY INVOKER;
CREATE TRIGGER "trg_update_transaction_id" AFTER UPDATE
ON "current_table" FOR EACH ROW
EXECUTE PROCEDURE "public"."update_transaction_id"();
So the column is transaction_id in the table current_table. The query executes fine and the my update function does run through this trigger. However, the transaction_id column remains the same value. Is there something wrong with this procedure?
There are three errors in your code. First, you use the equality operator = instead of the assignment operator :=. Second, you should not SETVAL the sequence; it knows perfectly well how to maintain itself. Third, this function should be called by a BEFORE UPDATE trigger or the assignment to transaction_id will not persist.
So why not simply:
CREATE FUNCTION update_transaction_id() RETURNS trigger AS $BODY$
BEGIN
NEW.transaction_id := nextval('seq_name');
RETURN NEW;
END;
$BODY$ LANGUAGE 'plpgsql';
You can trivially retrieve the immutable name of the sequence from the table definition, so plug that in straightaway.

function which returns as hstore datatype in postgresql

"hstoredata" is a variable of type hstore which contains key value pairs.
i.e. for ex: "hstoredata" variable contains the key value pairs '"ed"=>"1", "id"=>"1", "age"=>"27"'.
If "hstoredata" variable is passed to the function i.e select sampletest(hstoredata), function is returning as null.
-- Function: sampletest(hstore)
-- DROP FUNCTION sampletest(hstore)
CREATE OR REPLACE FUNCTION sampletest(hstoredata hstore)
RETURNS SETOF void AS
$BODY$
DECLARE
newhstoredata hstore;
BEGIN
newhstoredata := samplehstore(hstoredata);
RAISE NOTICE 'newhstoredata: %', newhstoredata;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION sampletest(hstore)
OWNER TO postgres;
Below is the program for function samplehstore(hstore)
-- Function: samplehstore(hstore)
-- DROP FUNCTION samplehstore(hstore)
CREATE OR REPLACE FUNCTION samplehstore(hstoredata hstore)
RETURNS SETOF void AS
$BODY$
BEGIN
RAISE NOTICE 'hstoredata: %', hstoredata;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION samplehstore(hstore)
OWNER TO postgres;
It's unclear what you're asking precisely, but based on the title, I assume you'd like your function to return something.
If so, the issue here is that you're declaring your function as returning setof void.
Declare it as returning whatever it should, and use return ... or return query ..., depending on what you actually need.