2015-02-26 11:08 GMT-03:00 Matheus Ferreira <[email protected]>:

> Muito obrigado pela ajuda
>
> Mas eu sou leigo na construção do script
>
>
>
> Você poderia me especificar o que cada comando faz para eu aprender....
>

Claro. Fiz um teste rápido aqui e parece estar funcionando também.

Seguinte, a ideia é chamar o dblink_exec e passar um texto (string) com o
comando SQL propriamente. Por exemplo, se inserir na tabela "processos2"
com os dados `idprocesso=1` e `nrprocesso='xpto'`, a ideia é fazer a
chamada dblink_exec da seguinte forma:

    PERFORM dblink_exec('...', $$INSERT INTO processo(idprocesso,
nrprocesso) VALUES('1', 'xpto')$$);

Assim, para fazer isso eu uso várias funções da contrib hstore [1] (você
deve instalá-la primeiro):

- hstore(NEW): transforma o registro NEW em um hstore (que é basicamente um
tipo chave/valor, sendo chave o nome da coluna e valor uma _string_ com o
conteúdo);
- each(...): função que retorna uma tabela com duas colunas "key" e
"value", cada linha é uma chave e um valor retirado do hstore, exemplo:

    postgres=# SELECT * FROM
each(hstore('"idprocesso"=>"1","nrprocesso"=>"xpto"'));
        key     | value
    ------------+-------
     idprocesso | 1
     nrprocesso | xpto
    (2 rows)

Explicando o código (vou modificá-lo um pouco para entender melhor):

DECLARE
   v_cmd text;
   ...
BEGIN;
    /**
     * Vamos fazer um SELECT que na verdade retorna uma
     * _string_ (ou text) com o comando SQL. Repare que
     * até a linha do debug isso é um comando só, cuidado
     * para não confundir.
     */
    SELECT
       /* começa a criação do comando com o INSERT na tabela em questão */
       'INSERT INTO processo('
       /*
        * each retorna várias linhas, usa string_agg para
        * agregar suas chaves separadas por vírgula e
        * usando quote_ident [2] para evitar SQL injection
        */
        || string_agg(quote_ident(key), ',')
        /* Adição dos valores */
        || ') VALUES('
        /**
         * Mesma ideia acima, usa o string_agg para agregar
         * os valores (retornados pelo each) e separando por
         * vírgula, junto com o quote_literal [2] para evitar
         * SQL injection e garantir escape correto das strings
         */
        || string_agg(quote_literal(value), ',') || ')'
    /* Salva o resultado dessa string na variável v_cmd */
    INTO v_cmd
    /* Retorna uma linha para cada chave (key) e valor (value) */
    FROM each(hstore(NEW));

    /* Debug: */
    RAISE NOTICE 'Comando: %', v_cmd;
    /* Execução: */
    PERFORM dblink_exec('...', v_cmd);

É isso, veja se ficou mais claro, tente executar pra ver (não testei em
detalhes, pode ter erros ainda).

Outra dica, ao invés de usar o dblink, você pode usar um FDW (que aceitam
escritas, a partir da 9.3 _se não me engano_), ficaria bem mais fácil já
que é só tratar a tabela estrangeira como se fosse uma local, daí o código
seria como passei primeiramente (quando não havia a informação de que
estava sendo usado o dblink).

[1] http://www.postgresql.org/docs/current/static/hstore.html
[2] http://www.postgresql.org/docs/current/static/functions-string.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
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a