2015-02-27 19:20 GMT-03:00 Matheus Saraiva <[email protected]>:

>         With chv as
>         (
>             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
>
>             ) 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, * from unnest(f_modulos) from chv c; -- Insere
> os módulos e suas liberações referentes à chave
>
>
> O erro está sendo:
>
>
>             ERROR:  syntax error at or near "from"
>             LINE 63: ...       ) select c.chave, * from unnest(f_modulos)
> from chv c...


Duplicar o FROM não faz sentido, se você quiser para cada valor do "unnest"
buscar um valor retornado pela CTE "chv", então use um vírgula ou CROSS
JOIN:

    INSERT INTO "Acessos" ...
    SELECT c.chave, u.*
    FROM unnest(f_modulos) AS u CROSS JOIN chv AS c;

Se me permite, tem várias decisões que você está tomando que u não faria
dessa forma, claro que são opiniões minha então veja se concorda ou não. Eu
evitaria as CTEs aninhadas como você fez, não é um problema mas é confuso,
e também não usaria os valores posicionais $n, mas o nome do parâmetro em
si (posicionais ficam confusos para grandes códigos), ficaria mais ou menos
assim (não testado):

    WITH insert_chaves AS (
        INSERT INTO "Chaves" (login, senha)
        VALUES (f_login, f_senha)
        RETURNING codigo -- Inserer a chave e retorna o código da mesma
    ), insert_fisicas AS (
        INSERT INTO "Fisicas" (pessoa, chave)
        SELECT person, k.codigo
        FROM insert_chaves k
        RETURNING chave -- Insere a pessoa na tabela de de pessoas Fisica e
retorna a chave
    )
    INSERT INTO "Acessos" (chave, modulo, liberacao)
    SELECT c.chave, m.*
    FROM unnest(f_modulos) AS m CROSS JOIN insert_fisicas c; -- Insere os
módulos e suas liberações referentes à chave

Outra coisa que eu evitaria é o nome de tabelas dessa forma (com letras
maiúsculas), ter que usar aspas em todo lugar é chato. Além disso, eu me
pergunto se sua escolha de usar tudo em funções PL/pgSQL pra *evitar* SQL
na aplicação foi mesmo uma boa escolha, e ainda mais o uso de arrays dessa
forma, mas talvez isso fuja um pouco do tópico desta thread.

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