Bem gente, graças á ajuda dos senhores consegui concluir a função para inserir 
clientes baseado na modelagem (http://oi61.tinypic.com/2zdpzdw.jpg)

Segue abaixo a função:

CREATE OR REPLACE FUNCTION "funcInsertClientes"
(
    f_nome character varying, 
    f_telefone character varying, 
    f_email character varying, 
    f_endereco integer, 
    f_imagem oid, f_rg character varying, 
    f_cpf character varying, 
    f_login character varying, 
    f_senha character varying, 
    f_modulos typeacesso[]
)
  RETURNS boolean AS
$BODY$

    declare 
        person integer;  -- Pessoa que está sendo inserida
    
    begin

                            --INSERE PESSOA E CLIENTE--
        With pess as
        (
                insert into "Pessoas" -- Inserre o cliente na tabela de pessoas
                (
                    nome,
                    telefone,
                    email,
                    endereco,
                    imagem
                ) values ($1, $2, $3, $4, $5) returning codigo -- Insere a 
pessoa e retorna o código
        ) 
        insert into "Clientes" -- Insere o cliente na tabela de clientes
        (
            pessoa,
            rg,
            cpf
        ) select p.codigo, $6, $7 from pess p returning pessoa into person;-- 
Insere o cliente e retorna o código (campo pessoa) para a variável person



                            --- INSERE CHAVE E FISICAS ---
        with kei as
        (
            insert into "Chaves" -- Inserer a chave (Login e Senha) na tabela 
de chaves
            (
                login,
                senha

            ) values ($8, $9) returning codigo -- Inserer a chave e retorna o 
código da mesma
                
        ), chv as 

        (  
            insert into "Fisicas"(pessoa, chave) select person, k.codigo from 
kei k returning chave -- Insere a pessoa na tabela de de pessoas Fisica e 
retorna a chave
        )
        Insert into "Acessos" -- Insere as liberações aos modulos na tabela 
Acessos
        (
            chave,
            modulo,
            liberacao

        ) select c.chave, m.* from unnest(f_modulos) as m cross join chv as c; 
-- Insere os modulos e suas liberações referentas à chave

        return true;

                                --- EXCEÇÕES ---
        exception

            when NOT_NULL_VIOLATION THEN
                RAISE NOTICE 'Required filds are blank';
                return false;
            when UNIQUE_VIOLATION THEN
                RAISE NOTICE 'One or more unique keys were violated';
                RETURN FALSE;
             WHEN RESTRICT_VIOLATION THEN
                RAISE NOTICE 'One or more restricts were violated';
                return false;
    end;

$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

Agradeço a dica do JOIN eu já conhecia o comando apesar do meu conhecimento de 
SQL não ser muito apurado, mas eu não imaginava que ele pudesse ser usado aqui, 
eu sempre usei apenas na manipulação de tabelas reais.

Resolvi remover a inserção dos dependentes e deixar em um função separada pois 
para dependentes existirá uma logica específica que será tratada na aplicação.
Sem falar que um dependente também pode ser associado a um cliente que já 
existe, por isso não faria sentido colocar aqui.
Acho até que daria para ficar tudo em uma única linha WITH, mas ficaria ainda 
mais confuso.
Bem está funcionando, gravando normalmente, porém ainda existe um problema, se 
a função cair em algumas das exceções, o processo é abortado, nada é gravado 
e a mensagem é retornada, porém, a sequencia da tabela "Pessoas" 
("Pessoas_codigo_seq") avança como se a transação houvesse ocorrido 
normalmente, como resolver?
SAVEPOINT + ROLLBACK ?


_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Reply via email to