PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Modifier le schéma de plusieurs fonctions PostgreSQL en une seule opération ?

Vous pouvez affiner davantage la boucle (en montrant uniquement la deuxième requête ):

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$;

Points majeurs

  • L'opérateur d'affectation dans plpgsql est := . = fonctionne, mais n'est pas documenté.

  • Supprimer les tables inutiles de FROM .

  • concat() peut être exagéré, mais format() simplifie la syntaxe.

Meilleure alternative basée sur les ensembles

La refonte du problème en tant qu'opération basée sur les ensembles est plus efficace. Un SELECT avec string_agg() fait le travail :

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$;