AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 9708
Accepted
Jeremy Holovacs
Jeremy Holovacs
Asked: 2011-12-25 11:34:24 +0800 CST2011-12-25 11:34:24 +0800 CST 2011-12-25 11:34:24 +0800 CST

有没有办法同时设置 PostgreSQL 数据库中所有对象的所有者?

  • 772

Stack Overflow Q & A Modify OWNER on all tables 同时在 PostgreSQL中描述了一些将表和其他对象更改为特定用户的绝妙方法,并且它工作得很好,但是所有建议似乎都忽略了我创建的函数。

是否有一种相当简单的方法来重置数据库中所有对象的所有者,包括函数?手工操作是非常不可取的。

postgresql functions
  • 5 5 个回答
  • 19957 Views

5 个回答

  • Voted
  1. Erwin Brandstetter
    2011-12-25T14:02:59+08:002011-12-25T14:02:59+08:00

    如果您确切地知道自己在做什么,那么您应该只直接操作系统目录。它可能会产生意想不到的副作用。或者,您可能会损坏数据库(或整个数据库集群)而无法修复。

    杰里米的回答虽然基本上可以解决问题,但不建议公众使用。它无条件地更改模式中的所有功能。您确定没有影响系统功能或附加模块安装的功能吗?
    更改已经属于指定所有者的功能的所有者也是没有意义的。

    首先,检查是否REASSIGN OWNED适合您:

    更改数据库角色拥有的数据库对象的所有权

    您必须列出所有要明确拒绝的角色。但它也重新分配了功能。

    将给定模式中的所有函数(而不是其他对象)分配给新所有者(可选地,不管以前的所有者):

    SELECT string_agg('ALTER FUNCTION '|| oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
    FROM   pg_catalog.pg_proc
    WHERE  pronamespace = 'public'::regnamespace
    -- AND relowner <> 'foo'::regrole
    -- AND proname ~~ 'f_%'
    

    这会生成规范的 SQL 命令ALTER FUNCTION ...来更改所有函数(在指定的模式中)。在执行之前检查命令 - 一个一个或一次全部:

    ALTER FUNCTION public.bar(text, text) OWNER TO foo;
    ALTER FUNCTION public.foo(x integer) OWNER TO foo;
    ...
    

    转换 toregprocedure产生一个带参数的有效函数名,在必要时用双引号括起来,在必要时为当前search_path.

    为了简单起见,还使用对象标识符类型regnamespaceregrole。

    WHERE我添加了一些您可能想要用来过滤结果的注释子句。

    您可以将所有这些放入DO语句或函数中,如相关答案中所示:

    • 删除命名空间中的所有函数?(执行生成的 DDL 命令?)

    对于 Postgres 9.4 或更早版本:

    SELECT string_agg('ALTER FUNCTION ' || oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
    FROM   pg_catalog.pg_proc p
    JOIN   pg_catalog.pg_namespace n ON n.oid = p.pronamespace
    WHERE  n.nspname = 'public'
    -- AND p.relowner <> (SELECT oid FROM pg_roles WHERE rolname = 'foo')
    -- AND p.proname ~~ 'f_%'
    

    聚合函数string_agg()需要 PostgreSQL 9.0 或更高版本。在旧版本中替换为array_agg()and array_to_string()。

    • 25
  2. JorSol
    2017-03-03T13:51:18+08:002017-03-03T13:51:18+08:00

    我使用此函数来更改表、函数、类型等的所有者。您可以更改游标的查询以使其适应您的需要。

    CREATE OR REPLACE FUNCTION fn_setowner(varchar(50), boolean) RETURNS void AS
    $BODY$
    DECLARE
    p_owner ALIAS FOR $1;
    p_debug ALIAS FOR $2;
    v_i integer := 0;
    v_sql text;
    
    --  CURSORS
    -- SCHEMA
    pesquemas CURSOR FOR
        SELECT quote_ident(schema_name) as nombre_esquema from information_schema.schemata WHERE schema_name NOT LIKE 'pg_%'
        and schema_name NOT IN ('information_schema') ORDER BY 1 ASC;
    
    -- TABLE
    ptablas CURSOR FOR
        SELECT quote_ident(table_schema) || '.' || quote_ident(table_name) as nombre_tabla, * FROM information_schema.tables
        WHERE table_schema NOT IN ('pg_catalog', 'information_schema')
        AND table_type <> 'FOREIGN TABLE' ORDER BY 1 ASC;
    
    -- FUNCTION
    pfunciones CURSOR FOR
        SELECT quote_ident(b.nspname) || '.' || quote_ident(a.proname) || '(' || pg_catalog.oidvectortypes(a.proargtypes) || ')' as nombre_function 
        FROM pg_proc a  INNER JOIN pg_namespace b on a.pronamespace = b.oid 
        WHERE b.nspname NOT IN ('pg_catalog', 'information_schema') AND proisagg = 'f'
        AND a.proname not like 'fsym_%' AND a.proname not like 'dblink%' ORDER BY 1 ASC;
    
    -- SEQUENCE
    psecuencias CURSOR FOR
        SELECT quote_ident(sequence_schema) || '.' || quote_ident(sequence_name) as nombre_secuencia FROM information_schema.sequences
        WHERE sequence_schema NOT IN ('pg_catalog', 'information_schema') ORDER BY 1 ASC;
    
    -- TYPE
    ptipos CURSOR FOR
        SELECT quote_ident(n.nspname) || '.' || quote_ident(t.typname) as nombre_tipo
        FROM pg_type t
        LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace 
        WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) 
        AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
        AND n.nspname NOT IN ('pg_catalog', 'information_schema') ORDER BY 1 ASC;
    
    
    BEGIN
    --  CHECK LOGIN
        IF NOT EXISTS (SELECT 1 FROM pg_user WHERE usename = p_owner) THEN                     
            RAISE EXCEPTION 'Login role not exists --> %', p_owner
                USING HINT = 'Please specify correct login and try again.';
        END IF;
    
        v_i = 0;
        if (p_debug) THEN
        RAISE NOTICE '--########## CHANGE SCHEMA OWNER ##########--';
        END IF;
        FOR resquema IN pesquemas LOOP
            v_sql = 'ALTER SCHEMA ' || resquema.nombre_esquema || ' OWNER TO ' || quote_ident(p_owner) || ';';
            if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
            EXECUTE v_sql;
            v_i = v_i + 1;
        END LOOP;
        if (p_debug) THEN
        RAISE NOTICE '--@@@@@@ SCHEMAS WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
        END IF;
    
        v_i = 0;
        if (p_debug) THEN
        RAISE NOTICE '--########## CHANGE TABLE OWNER ##########--';
        END IF;
        FOR rtables IN  ptablas LOOP
            v_sql = 'ALTER TABLE ' || rtables.nombre_tabla || ' OWNER TO ' || quote_ident(p_owner) || ';';
            if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
            EXECUTE v_sql;
            v_i = v_i + 1;
        END LOOP;
        if (p_debug) THEN
        RAISE NOTICE '--@@@@@@ TABLES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
        END IF;
    
        v_i = 0;
        if (p_debug) THEN
        RAISE NOTICE '--########## CHANGE FUNCTION OWNER ##########--';
        END IF;
        FOR rfunction IN  pfunciones LOOP
            v_sql = 'ALTER FUNCTION ' || rfunction.nombre_function || ' OWNER TO ' || quote_ident(p_owner) || ';';
            if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
            EXECUTE v_sql;
            v_i = v_i + 1;
        END LOOP;
        if (p_debug) THEN
        RAISE NOTICE '--@@@@@@ FUNCTIONS WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
        END IF;
    
        v_i = 0;
        if (p_debug) THEN
        RAISE NOTICE '--########## CHANGE SEQUENCE OWNER ########## --';
        END IF;
        FOR rsecuencias IN  psecuencias LOOP
            v_sql = 'ALTER TABLE ' || rsecuencias.nombre_secuencia || ' OWNER TO ' || quote_ident(p_owner) || ';';             
            if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
            EXECUTE v_sql;
            v_i = v_i + 1;
        END LOOP;
        if (p_debug) THEN
        RAISE NOTICE '--@@@@@@ SEQUENCES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
        END IF;
    
        v_i = 0;
        if (p_debug) THEN
        RAISE NOTICE '--########## CHANGE TYPE OWNER ##########--';
        END IF;
        FOR rtipos IN  ptipos LOOP                
            v_sql = 'ALTER TYPE ' || rtipos.nombre_tipo || ' OWNER TO ' || quote_ident(p_owner) || ';';                
            if (p_debug) THEN RAISE NOTICE '%', v_sql; END IF;
            EXECUTE v_sql;
            v_i = v_i + 1;
        END LOOP;
        if (p_debug) THEN
        RAISE NOTICE '--@@@@@@  TYPES WITH OWNER % TOTAL = % @@@@@@--', p_owner, CAST(v_i AS VARCHAR);
        END IF;
    
    END;
    $BODY$
      LANGUAGE 'plpgsql' VOLATILE
      COST 100;
    

    然后我就执行(如果要调试输出只需将第二个参数设置为 true):

    SELECT fn_setowner('demo', false);
    DROP FUNCTION fn_setowner(varchar(30), boolean);
    
    • 1
  3. Anton Smolkov
    2017-09-07T01:06:43+08:002017-09-07T01:06:43+08:00

    这应该适用于功能:

    IFS=$'\n'
    for fnc in `psql -qAt -c "SELECT  '\"' || p.proname||'\"' || '(' || pg_catalog.pg_get_function_identity_arguments(p.oid) || ')' FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE n.nspname = 'public';" YOUR_DB`
    do
      psql -c "alter function $fnc owner to NEW_OWNER" YOUR_DB
    done
    
    • 1
  4. kangoprex
    2021-06-16T20:25:03+08:002021-06-16T20:25:03+08:00

    只需转储数据库模式,然后使用 GnSa 或“Grep n Sed away”

    pg_dump DBNAME -s | grep -E "OWNER TO" | sed -E "s/(OWNER TO )ownerA/\1ownerB/" | psql DBNAME
    
    
    • 0
  5. Best Answer
    Jeremy Holovacs
    2011-12-25T11:58:27+08:002011-12-25T11:58:27+08:00

    好吧,我没有找到一个一步的过程,但这会处理我在数据库中可以看到的所有对象:

    update pg_class 
    SET relowner = (SELECT oid FROM pg_roles WHERE rolname = 'foo')
    where relnamespace = (select oid 
                          from pg_namespace 
                          where nspname = 'public' 
                          limit 1);
    
    update pg_proc 
    set proowner = (select oid from pg_roles where rolname = 'foo')
    where pronamespace = (select oid 
                          from pg_namespace 
                          where nspname = 'public' 
                          limit 1);
    
    • -8

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve