Arquivos

Posts Tagged ‘plpgsql’

Uma palavra sobre instruções dinâmicas plpgsql e plperl

fevereiro 8, 2008 Deixe um comentário

Problema recorrente e chato de se encarar é a necessidade de trabalhar com expressões dinâmicas na linguagem plpgsql.

De fato a linguagem plpgsql possue uma característica que permite que o plano de execução seja salvo na primeira chamada para uma instrução, desta forma dispensando a etapa de planejamento na próxima vez em que aquela instrução for executada dentro daquela mesma sessão e optimizando o acesso. Por este motivo, para situações regulares onde se é necessário criar instruções dinâmicas, o uso do comando EXECUTE dentro de funções é aconselhado, com o preço do não-salvamento dos planos de execução dos trechos de código onde este comando foi utilizado (senão, não era dinâmico ;-) ).

Porém, pense na seguinte situação:

<code>

Tipo.atributo := OutroTipo.outroAtributo;

</code>

Se quisermos atribuir OutroTipo.outroAtributo de forma que “outroAtributo” for uma expressão gerada em tempo de execução, não conseguiremos utilizando plpgsql, pelo facto da variável OutroTipo fazer parte do contexto de variáveis do plpgsql e por este motivo não aceitando substituição com o comando EXECUTE.
Então, logo:

FOR i IN 1..10 LOOP

EXECUTE OutroTipo.array[i] INTO Tipo.atributo;

ou qualquer outro tipo de atribuição dinâmica não deverá funcionar, causando uma exceção não-recuperável.

Quando se tem necessidade específica para geração de comandos dinâmicos e expressões complexas, o jeito mesmo é partir para outras linguagens procedurais que manipulem as construções SQL como texto puro ao invés de objetos gravados em memória.

O seguinte trecho em plperl propõe uma solução para o problema em questão:

@columns = (chave,valor1,valor2…);

$row = spi_exec_query($sql);

foreach(@columns[1..$#columns]){
push @$TipoAtributo, { chave=> $row->{@columns[0]},valor1=> $row->{$_}}
}

Agora o hash TipoAtributo possue os valores que supostamente não se conseguia recuperar com plpgsql.

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.