2012/5/20 Anselmo Silva <anselmo....@gmail.com>

> Qual versão do PostgreSQL fizeste?
>
> Resultado:
> ao criar a função :
> AVISO:  uso de escape fora do padrão em cadeia de caracteres
> LINE 1: SELECT 'SELECT ' || regexp_replace(calculo, '([0-9]+)([^\.0-...
>
> ao executá-la usando: *Calcule ('1/10')*
>
> ERRO: erro de sintaxe em ou próximo a " "
> SQL state: 42601
> Context: PL/pgSQL function "calcule" line 4 at comando EXECUTE
>


Não era para usar o escape por padrão.

Corrigindo para funcionar em qualquer versão:

CREATE OR REPLACE FUNCTION public.calcule(calculo text)
RETURNS numeric
LANGUAGE plpgsql
AS $function$
DECLARE
    v_result numeric;
BEGIN
    EXECUTE 'SELECT ' || regexp_replace(calculo, E'([0-9]+)([^\\.0-9])',
E'\\1::numeric\\2', 'g')
    INTO v_result;
    RETURN v_result;
END;
$function$;

Testado na 9.1. Não tive tempo ontem, mas vou explicar o que a função faz,
como não testei muito pode ser que precise de ajustes. Esta função vai
pegar todo número inteiro e colocar ::numeric na frente (para ver o
resultado você pode usar um RAISE), em seguida dá um execute nesse
resultado.

Explicado a expressão regular, o padrão E'([0-9]+)([^\\.0-9])' vai procurar
por caracteres de 0 a 9 seguidos de um caractere que *não* seja ponto
(resumindo, um inteiro). O valor de substituição E'\\1::numeric\\2' vai
trocar o inteiro por ele mesmo mais o cast para numeric, e colocar de volta
o caractere que não é ponto.

Se for usar isso mesmo, faça um milhão de testes e ainda use try-catch na
aplicação onde estiver usando, pois o que você passar também corre o risco
de estar mal-formado. Apesar que estou achando essa função interessante
para ser usada em fórmulas definidas pelo usuário.

Atenciosamente,
--
Matheus de Oliveira
_______________________________________________
pgbr-geral mailing list
pgbr-geral@listas.postgresql.org.br
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral

Responder a