Issue
Suppose I have an array of state abbreviations like this:
states text[] := ARRAY['al', 'ak', 'az', 'ar', 'ca',
'co', 'ct', 'de', 'dc', 'fl', 'ga', 'hi', 'id', 'il',
'in', 'ia', 'ks', 'ky', 'la', 'me', 'md', 'ma', 'mi',
'mn', 'ms', 'mo', 'mt', 'ne', 'nv', 'nh', 'nj', 'nm',
'ny', 'nc', 'nd', 'oh', 'ok', 'or', 'pa', 'ri', 'sc',
'sd', 'tn', 'tx', 'ut', 'vt', 'va', 'wa', 'wv', 'wi',
'wy', 'pr', 'vi'];
I want to loop or iterate through this array list and plug the individual state abbreviations into a function as a parameter and run it. Note: I also have the same data in a table called states
under the same schema with a column called st_abbr
. Here’s the function:
CREATE OR REPLACE FUNCTION pop_allocation_sql.st_fips_updater2(
st_abbr text
)
RETURNS VOID
AS
$$
DECLARE
BEGIN
-- logic
EXECUTE format(
'UPDATE pop_allocation_output_12102021.%s_population_allocation_20210202
SET st_fips = LEFT(geoid, 2)
WHERE st_fips <> LEFT(geoid, 2)',
st_abbr);
END;
$$ LANGUAGE plpgsql
VOLATILE;
How would I do that?
Solution
No need to use a loop, you can use unnest()
to generate one row for each array element.
select pop_allocation_sql.st_fips_updater2(state)
from unnest(ARRAY['al', 'ak', 'az', 'ar', 'ca',
'co', 'ct', 'de', 'dc', 'fl', 'ga', 'hi', 'id', 'il',
'in', 'ia', 'ks', 'ky', 'la', 'me', 'md', 'ma', 'mi',
'mn', 'ms', 'mo', 'mt', 'ne', 'nv', 'nh', 'nj', 'nm',
'ny', 'nc', 'nd', 'oh', 'ok', 'or', 'pa', 'ri', 'sc',
'sd', 'tn', 'tx', 'ut', 'vt', 'va', 'wa', 'wv', 'wi',
'wy', 'pr', 'vi']) as t(state);
If those abbreviations are available in a different table, there is no need to use an array or a variable:
select pop_allocation_sql.st_fips_updater2(st_abbr)
from states
But your data model seems rather strange. You shouldn’t have one table for each state, but a single table where state
is a column.
Answered By – a_horse_with_no_name
Answer Checked By – Terry (BugsFixing Volunteer)