2013/12/15 Guimarães Faria Corcete DUTRA, Leandro <l...@dutras.org>

> 2013/12/15 Wellington <wm...@yahoo.com.br>:
> >
> > tenho uma duvida: Eh possivel fazer uma consulta das sequencias que nao
> > estao sendo utilizadas em nenhuma tabela ?
>
> Sim, pelo catálogo, como sempre.  Pense MINUS.
>
>
>

Exatamente. Se quisermos verificar as sequências que não estão no valor
padrão (default) de um atributo, podemos relacionar a pg_class para
recuperar todas as sequências (são aquelas cujo atributo relkind = 'S') com
a tabela pg_attrdef que possui o padrão de um campo (atributo adsrc). Por
exemplo:

    SELECT r.oid::regclass
    FROM pg_class r LEFT JOIN pg_attrdef d ON d.adsrc LIKE
'%'||(r.oid::regclass::text)||'%'
    WHERE r.relkind = 'S' AND d.oid IS NULL;

Ao menos que use nomes estranhos em suas sequências, esta consulta
funcionará perfeitamente.



>  > Pelo que percebi, ao excluir uma tabela, a sequencia associada a ela
> nao é
> > excluida.
>
> Porque não há associação de fato.  Uma seqüência pode servir várias
> tabelas, ou nenhuma.
>

Bem, não é **exatamente** assim. Por exemplo, quando cria-se uma sequência
utilizando o pseudo-tipo serial, o PostgreSQL irá sim associar a sequência
a uma tabela (na verdade ao atributo da tabela, e somente a um). Vejam o
exemplo:

    postgres=# CREATE TABLE seq_test(a serial);
    CREATE TABLE
    ==> a sequência foi *criada* implicitamente
    postgres=# SELECT nextval('seq_test_a_seq');
     nextval
    ---------
           1
    (1 row)

    postgres=# DROP TABLE seq_test;
    DROP TABLE
    ==> a sequência foi *excluída* implicitamente
    postgres=# SELECT nextval('seq_test_a_seq');
    ERROR:  relation "seq_test_a_seq" does not exist
    LINE 1: SELECT nextval('seq_test_a_seq');

Essa associação é feita usando o OWNED BY nos comandos CREATE/ALTER
SEQUENCE. Por exemplo, o código acima é exatamente equivalente a:

    CREATE SEQUENCE seq_test_a_seq;
    CREATE TABLE seq_test(a integer not null default
nextval('seq_test_a_seq'));
    ALTER SEQUENCE seq_test_a_seq OWNED BY seq_test.a;

Com isso, a sequência passa a estar associada à tabela "seq_test" e
atributo "a".

A vantagem é que, além de uma deleção da tabela também remover a sequência,
podemos forçar o TRUNCATE a zerar a sequência:

    TRUNCATE seq_test RESTART IDENTITY;

Houve uma discussão sobre isso ano passado, e cheguei a criar uma consulta
para pegar as sequências e suas associações [1]. A mesma pode ser adaptada
para recuperar as sequências que não estão associadas a nenhum atributo (em
geral elas deveriam, mas não é uma regra):

    SELECT s.oid::regclass AS sequence
    FROM pg_class s
        LEFT JOIN pg_depend d ON s.oid = d.objid AND d.deptype = 'a'
         LEFT JOIN pg_class t ON d.refobjid = t.oid
         LEFT JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum =
d.refobjsubid
    WHERE s.relkind = 'S' AND t.oid IS NULL;


[1]
http://listas.postgresql.org.br/pipermail/pgbr-geral/2012-August/031827.html

Atenciosamente,
-- 
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a