Mostrando postagens com marcador PostgreSQL. Mostrar todas as postagens
Mostrando postagens com marcador PostgreSQL. Mostrar todas as postagens

sexta-feira, 5 de junho de 2009

PostgreSQL: restringir estados brasileiros

Precisei restringir as UFs no banco de dados e, ao invés de criar CHECKs em cada uma das tabelas, preferi criar um ENUM e não achei nenhum pronto, então disponibilizo:

CREATE TYPE estados_brasil AS ENUM('AC', 'AL', 'AP', 'AM', 'BA', 'CE', 'DF', 'GO', 'ES', 'MA', 'MT', 'MS', 'MG', 'PA', 'PB', 'PR', 'PE', 'PI', 'RJ', 'RN', 'RS', 'RO', 'RR', 'SP', 'SC', 'SE', 'TO');

A outra opção seria criar um DOMAIN e restringir no CHECK, mas acho que neste caso o TYPE é mais indicado.

quarta-feira, 3 de outubro de 2007

PG Conference Brasil 2007

Como um bom evangelista desenvolvedor Postgres, fiquei empolgado em ver que estão confirmadas presenças internacionais na conferência nacional (Josh Berkus e Bruce Momjian).

Parabéns à equipe de organização, farei o possível para participar.

Os que tiverem interesse, há mais detalhes em http://www.temporealeventos.com.br/?area=80

terça-feira, 10 de abril de 2007

Calculando dígito verificador (DV) para contas da Caixa Econômica Federal (CEF)

Hoje me deparei com uma situação: estou fazendo uma integração com a CEF e muitas vezes tenho registros rejeitados pois o DV da conta está incorreto.

Minha primeira pergunta: como calculo o dígito verificador? Descobri, por contato telefônico, que é pelo módulo 11.
Desta forma, encontrei uma referência no Wikipedia. Porém, ao calcular, não batia (eu possuo poupança na CEF e serviu para testes...).
Após mais alguns passos no Google, achei uma referência interessante (role direto para a página 3). É necessário considerar, também, a agência e operação de conta!

Agora, com o algoritmo claramente definido, implementei a função em PostgreSQL (pl/pgsql), que ficou assim (a formatação foi perdida quando colei... mais tarde tento aprender a fazer isto):

CREATE OR REPLACE FUNCTION calculaDigitoCaixa(_dados varchar) RETURNS int2 AS $$
DECLARE
i integer;
peso integer;
base integer;
total integer;
resto integer;
dados varchar;
BEGIN
-- Verificar a consistência dos dados!
dados := COALESCE(_dados, '');
IF (LENGTH(COALESCE(_dados, '')) != 15) THEN
RAISE WARNING 'Dados não contém um tamanho válido! Tamanho: % Nulo: % Entrada: %', LENGTH(dados), _dados IS NULL, dados;
END IF;

peso := null;
total := 0;
-- Iniciar cálculo...
FOR i IN REVERSE LENGTH(dados)..1 LOOP
-- Qual peso?
IF (COALESCE(peso, 10) >= 9) THEN
peso := 2;
ELSE
peso := peso + 1;END IF;
-- Qual base?
base := SUBSTR(dados, i, 1)::int;

RAISE NOTICE 'Peso % * Base %', peso, base;
-- multiplica base * peso e acumula total
total := total + base * peso;
END LOOP;
RAISE NOTICE 'Total: %', total;
-- Multiplicar total por 10
total := total * 10;

-- O resultado então é o resto da divisão por 11. Caso seja 10, então é 0.
resto := total % 11;

RAISE NOTICE 'Resto: %', resto;
IF (resto = 10) THEN
resto := 0;
END IF;

RETURN resto;
END;
$$ LANGUAGE plpgsql IMMUTABLE;

Coloquei a mesma IMMUTABLE, pois sempre haverá o mesmo retorno para uma mesma entrada (documentação)...

Agora basta validar, por exemplo:

SELECT calculaDigitoCaixa(agencia, operacao_conta, conta) FROM fornecedor ...