AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 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

Existe um meio de definir o proprietário de todos os objetos em um banco de dados PostgreSQL ao mesmo tempo?

  • 772

O Stack Overflow Q & A Modify OWNER em todas as tabelas simultaneamente no PostgreSQL descreve algumas maneiras bacanas de alterar a tabela e outros objetos para um usuário específico e funciona perfeitamente, no entanto, todas as sugestões parecem ignorar as funções que criei.

Existe uma maneira bastante fácil de redefinir o proprietário de TODOS os objetos no banco de dados, incluindo as funções? Fazer isso manualmente é altamente indesejável.

postgresql functions
  • 5 5 respostas
  • 19957 Views

5 respostas

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

    Você só deve manipular os catálogos do sistema diretamente, se souber exatamente o que está fazendo. Pode ter efeitos colaterais inesperados. Ou você pode corromper o banco de dados (ou todo o cluster de banco de dados) além do reparo.

    A resposta de Jeremy , embora basicamente faça o truque, não é aconselhável para o público em geral. Ele altera incondicionalmente todas as funções em um esquema. Tem certeza de que não há funções do sistema afetadas ou funções instaladas por um módulo adicional?
    Também seria inútil alterar o proprietário de funções que já pertencem ao proprietário designado.

    Primeiro, verifique se REASSIGN OWNEDpode funcionar para você:

    alterar a propriedade de objetos de banco de dados pertencentes a uma função de banco de dados

    Você deve listar todas as funções a serem rejeitadas explicitamente. Mas também reatribui funções .

    Para atribuir todas as funções (e nenhum outro objeto) em um determinado esquema a um novo proprietário (opcionalmente, independentemente do proprietário anterior):

    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_%'
    

    Isso gera os comandos SQL canônicosALTER FUNCTION ... para alterar todas as funções (no esquema especificado). Inspecione os comandos antes de executar - um por um ou todos de uma vez:

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

    A conversão para regprocedureproduz um nome de função válido com parâmetros, entre aspas duplas quando necessário, qualificado pelo esquema quando necessário para o search_path.

    Também usando os tipos de identificador de objeto regnamespaceeregrole para simplificar.

    Adicionei algumas cláusulas comentadas WHEREque você pode querer usar para filtrar os resultados.

    Você pode colocar tudo isso em uma DOdeclaração ou função, como demonstrado nesta resposta relacionada:

    • Soltar todas as funções em um namespace? (Executar comandos DDL gerados?)

    Para Postgres 9.4 ou mais antigo :

    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_%'
    

    A função agregada string_agg()requer PostgreSQL 9.0 ou posterior. Na versão mais antiga, substitua por array_agg()e array_to_string().

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

    Utilizo esta função para alterar o dono de tabelas, funções, tipos, etc. Você pode alterar a consulta dos cursores para adaptá-la às suas necessidades.

    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;
    

    Então eu apenas executo (se você quiser depurar a saída, simplesmente defina o segundo parâmetro como verdadeiro):

    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

    Isso deve funcionar para as funções:

    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

    apenas despeje o esquema do banco de dados e use GnSa ou "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

    Bem, não encontrei um processo de uma etapa, mas isso cuida de todos os objetos que posso ver em meu banco de dados:

    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

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

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

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve