17 agosto 2011

Gerar dígito verificador EAN13 no FB


Pessoal, pra quem precisa gerar automaticamente o dígito verificador para código de barras direto pelo DB, vai uma stored procedure muito simples, mas que te poupa muito tempo: a geração do dígito verificador.



SET TERM ^ ;

create or alter procedure GERADVEAN13 (
CODIGOBARRAS varchar(12))
returns (
DIGITOVERIFICADOR integer)
as
declare variable SOMA integer;
begin
/* Gera Digito verificador para códigos EAN13, digitando como entrada os 12 digitos iniciais do código */

SOMA = 0;

SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 1 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 2 FOR 1) as Integer)*3);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 3 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 4 FOR 1) as Integer)*3);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 5 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 6 FOR 1) as Integer)*3);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 7 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 8 FOR 1) as Integer)*3);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 9 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 10 FOR 1) as Integer)*3);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 11 FOR 1) as Integer)*1);


SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 12 FOR 1) as Integer)*3);


IF ((((:SOMA/10.00)-(:SOMA/10)) *10)=0) THEN

begin
digitoverificador = 0 ;
end
else
begin
digitoverificador = 10-( ((:SOMA/10.00)-(:SOMA/10)) *10 ) ;
end

SUSPEND;

end^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE GERADVEAN13 TO SYSDBA;

6 comentários:

  1. Gostei da dica mais só esta retornando vazio fazendo direto no banco.

    ResponderExcluir
  2. Olá Erick. Essa procedure gera DV de código EAN-13, então deve-se passar como parâmetro na chamda o código com 12 digitos para que ela retorne o 13º que é o verificador.

    Ex: select * from geradvean13('789820327290');

    Nesse caso vai te retornar 3 que é o verificador para este código.

    ResponderExcluir
  3. Gostaria de saber o que estou fazendo errado pois só retorna 0 agora

    CREATE PROCEDURE SP_DIGITOEAN (
    codigobarras varchar(12))
    returns (
    digito integer)
    as
    declare variable soma integer;
    begin
    SOMA = 0;
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 1 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 2 FOR 1) as Integer)*3);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 3 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 4 FOR 1) as Integer)*3);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 5 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 6 FOR 1) as Integer)*3);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 7 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 8 FOR 1) as Integer)*3);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 9 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 10 FOR 1) as Integer)*3);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 11 FOR 1) as Integer)*1);
    SOMA = :SOMA + (Cast(SubString( :CODIGOBARRAS FROM 12 FOR 1) as Integer)*3);

    IF ((((:SOMA/10.00)-(:SOMA/10))*10)=0) THEN
    BEGIN
    DIGITO = 0;
    END
    ELSE
    BEGIN
    DIGITO = 10-(((:SOMA/10.00)-(:SOMA/10))*10);
    END

    suspend;

    ResponderExcluir
    Respostas
    1. Você deve chamar essa sp com um SELECT, pois ela tem a cláusula suspend no código, passando como parâmetro somente os 12 digitos do código de barras.

      Exemplo:

      1) select *
      from geradvean13('400999390209') === RETORNA 0

      2) select *
      from geradvean13('978857542108') ==== RETORNA 6

      3) select digitoverificador
      from geradvean13('978857393539')
      into :Variavel ==== RETORNA 4
      ==== E GRAVA NA
      ==== VARIAVEL

      Excluir
  4. O problema é o dialeto, pois, no atual banco utilizo o dialeto 1 testei em outro com dialeto 3 e deu certo Obrigado pela bela função.

    ResponderExcluir
  5. Consegui com uma ajudinha funcionar no dialeto 1 e 3 no final basta fazer esta alteração e dá tudo certo.
    Vlw cara pela iniciativa de disponibilizar o código e dar respostas quando pedido. Obrigado.

    IF (( mod(:SOMA,10) )=0) THEN
    BEGIN
    DIGITO = 0;
    END
    ELSE
    BEGIN
    DIGITO = 10 - ( mod(:SOMA,10) );
    END

    ResponderExcluir