Change schema of multiple PostgreSQL functions in one operation?
Answer a question Recently I needed to move objects from PostgreSQL's default schema "public" to another schema. I found this post which shows how to move tables which was great, but I also need to mo
Answer a question
Recently I needed to move objects from PostgreSQL's default schema "public" to another schema. I found this post which shows how to move tables which was great, but I also need to move the functions.
Answers
You could refine the loop some more (demonstrating only the second query):
DO
$do$
DECLARE
r record;
sql text = '';
BEGIN
FOR r IN
SELECT p.proname, pg_get_function_identity_arguments(p.oid) AS params
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE nspname = 'public'
-- and other conditions, if needed
LOOP
sql := sql
|| format(E'\nALTER FUNCTION public.%I(%s) SET SCHEMA new_schema;'
,r.proname, r.params);
END LOOP;
RAISE NOTICE '%', sql; -- for viewing the sql before executing it
-- EXECUTE sql; -- for executing the sql
END
$do$;
Major points
-
Assignment operator in plpgsql is
:=
.=
works, but is undocumented. -
Remove unneeded tables from
FROM
. -
concat()
may be overkill, butformat()
simplifies the syntax.
Better set-based alternative
Re-casting the problem as set-based operation is more effective. One SELECT with string_agg()
does the job:
DO
$do$
DECLARE
sql text;
BEGIN
SELECT INTO sql
string_agg(format('ALTER FUNCTION public.%I(%s) SET SCHEMA new_schema;'
,p.proname, pg_get_function_identity_arguments(p.oid)), E'\n')
FROM pg_proc p
JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE nspname = 'public';
-- and other conditions, if needed
RAISE NOTICE '%', sql; -- for viewing the sql before executing it
-- EXECUTE sql; -- for executing the sql
END
$do$;
更多推荐
所有评论(0)