2

最近、オブジェクトを PostgreSQL のデフォルト スキーマ「public」から別のスキーマに移動する必要がありました。テーブルを移動する方法を示すこの投稿は素晴らしかったですが、関数も移動する必要があります

4

2 に答える 2

3

ループをさらに改良することができます ( 2 番目のクエリのみを示します)。

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

主なポイント

  • plpgsql の代入演算子は:=. =動作しますが、文書化されていません。

  • から不要なテーブルを削除しFROMます。

  • concat()やり過ぎかもしれませんがformat()、構文を簡素化します。

より良いセットベースの代替

セットベースの操作として問題を再キャストすると、より効果的です。1 つの SELECT でstring_agg()ジョブを実行します。

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$;
于 2013-10-03T00:19:20.560 に答える
0
DO$$
DECLARE
    row record;
BEGIN
    FOR row IN SELECT tablename FROM pg_tables WHERE schemaname = 'public' -- and other conditions, if needed
    LOOP
        EXECUTE 'ALTER TABLE public.' || quote_ident(row.tablename) || ' SET SCHEMA [new_schema];';
    END LOOP;
END;
$$;

DO$$
DECLARE
    row record;
    sql text = E'\n';
BEGIN
    FOR row IN
        SELECT
               proname::text as 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 = CONCAT(sql, E'\n',
            'ALTER FUNCTION public.', row.proname,
            '(', row.params, ') SET SCHEMA [new_schema];');
    END LOOP;
    RAISE NOTICE '%', sql; -- for viewing the sql before executing it
    -- EXECUTE sql; -- for executing the sql
END;$$;
于 2013-10-02T22:47:45.387 に答える