I have a plpgslq
function which does some data processing and would like to write a for
loop, however my table name is not known at design time. Is there any possible way to achieve this? Here is sample code snippet of what I want to achieve:
-- Function: check_data()
-- DROP FUNCTION check_data();
CREATE OR REPLACE FUNCTION check_data()
RETURNS character varying AS
$BODY$declare
dyn_rec record;
tbl_name record;
begin
-- sample dynamic tables
tbl_name := 'cars';
tbl_name := 'trucks';
tbl_name := 'bicycles';
for dyn_rec in select * from format($$s%$$,tbl_name) loop
raise notice 'item is %',dyn_rec.item_no;
end loop;
return 'Processing Ok';
end;$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
ALTER FUNCTION check_data()
OWNER TO postgres;
Developers can use dynamic SQL to construct and run SQL queries at run time as a string, using some logic in SQL to construct varying query strings, without having to pre-construct them during development. There are two options for running dynamic SQL: use the EXECUTE command or the sp_executesql function.
Dynamic SQL is used to reduce repetitive tasks when it comes to querying. For example, one could use dynamic SQL to create table partitioning for a certain table on a daily basis, to add missing indexes on all foreign keys, or add data auditing capabilities to a certain table without major coding effects.
The FOREACH statement to loop over an array is: [ << label >> ] FOREACH target [ SLICE number ] IN ARRAY expression LOOP statements END LOOP [ label ];
Turns out you can. PostgreSQL also supports other procedural languages such as Python, C and my favourite, JavaScript! To be able to write JavaScript for your PostgreSQL function, you have to ensure that PL/v8 has been installed on your database server.
You cannot use a variable as table or column identifier in plpgsql embedded SQL ever. A solution is dynamic SQL - EXECUTE or FOR IN EXECUTE statements:
DO $$
DECLARE
tables text[] = ARRAY['table1','table2'];
table_name text;
rec record;
BEGIN
FOREACH table_name IN ARRAY tables
LOOP
FOR r IN EXECUTE format('SELECT * FROM %I', table_name)
LOOP
RAISE NOTICE '%', rec;
END LOOP;
END LOOP;
END; $$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With