Uma das coisas mais básicas que encontramos na programação é a conversão de texto para número. Isto muitas vezes ocorre porque extraímos o valor de que precisamos de um texto, mas enquanto o valor ainda for do tipo texto não poderemos fazer operações matemáticas como somar ou subtrair. Para resolver o problema é preciso fazer a conversão.
A SQL Function abaixo resolve este problema, ela possui dois parametros de entrada:
- String com o valor: Por exemplo ‘R$ 1.123,4567’
- Valor assumido caso a conversão falhe: Assume zero, mas você pode trocar o valor.
E retorna NUMERIC(18,4), mas eu sei que muitos de vocês preferem valores com 2 casas decimais, portanto onde vê NUMERIC(18,4) no código psql basta trocar por NUMERIC(18,2):
create or alter function STR_TO_NUMERIC4 ( P_VALUE_AS_TEXT varchar(30), P_VALUE_DEFAULT_IF_FAILS numeric(18,4) = 0) returns numeric(18,4) as BEGIN /* essa procedure/função retorna um numeric(18, 4) a partir de um tipo texto exibido como numero, por exemplo, '1.234,5678' O resultado será o numeric(18,4) 1234.5678 já no formato SQL decimal O segundo parametro é o valor que deverá ser retornado caso o texto númerico não seja válido, ex: a=STR_TO_NUMERIC4('R$ 1.234,5678', 0); Visto que nesse exemplo o R$ não deveria existir então retornará zero. O sistema analisa a string da direita para a esquerda a fim de determinar qual é o sinal de decimal, se ele encontrar primeiro a virgula, então a virgula será o decimal, se ele encontrar o ponto então o ponto será o decimal e o inverso será o separador de milhar by gladiston.santana[em]gmail.com */ P_VALUE_AS_TEXT=trim(:P_VALUE_AS_TEXT); if (:P_VALUE_AS_TEXT is null) then P_VALUE_AS_TEXT=cast(P_VALUE_DEFAULT_IF_FAILS as varchar(30)); P_VALUE_AS_TEXT=trim(:P_VALUE_AS_TEXT); if (:P_VALUE_AS_TEXT='') then P_VALUE_AS_TEXT=cast(P_VALUE_DEFAULT_IF_FAILS as varchar(30)); if (position (',' in :P_VALUE_AS_TEXT)>0) then begin P_VALUE_AS_TEXT=replace (:P_VALUE_AS_TEXT, ',', '.'); end P_VALUE_AS_TEXT=trim(:P_VALUE_AS_TEXT); return cast(P_VALUE_AS_TEXT AS numeric(18,4)); END
Modo de Usar
s='12.345,6789'; n=STR_TO_NUMERIC4(s, 0); -- retorna 12345.6789 s='R$ 12.345,6789'; n=STR_TO_NUMERIC4(s, 0); -- retorna zero porque R$ tornará o número inválido
Conclusion
O exemplo acima com pouca modificação você pode deixar o numero de casas decimais dinâmico. ou até mesmo permitir que ‘R$’ seja ignorado dentro de uma string, o ponto é, temos agora uma maneira simples de converter um texto para um numero.