[firebase-br] Dígito verificador

Flavio Divino flaviodivino em gmail.com
Qui Jun 11 08:09:23 -03 2015


Bom dia Fábio,

Tenho duas procedures que podem te ajudar nesse problema.
A primeira é essa que faz a função de truncar (tive que fazer essa
procedure por causa da minha versão do firebird 2.0)
SET TERM ^ ;

create or alter procedure SP_TRUNC (
    FLOATVALUE double precision,
    DECIMALS smallint)
returns (
    RESULT double precision)
as
declare variable STRVALUE varchar(50);
declare variable STRINT varchar(50);
declare variable STRFRAC varchar(50);
declare variable AFTERSEP smallint;
declare variable DECCOUNT smallint;
BEGIN
  IF (FloatValue IS NULL) THEN
    Result = NULL;
  ELSE
  BEGIN
    StrValue = FloatValue;
    StrInt = '';
    StrFrac = '';
    AfterSep = 0;
    DecCount = 0;
    WHILE (StrValue <> '') DO
    BEGIN
      IF (SUBSTRING(StrValue FROM 1 FOR 1) = '.') THEN
        AfterSep = 1;
      ELSE
      BEGIN
        IF (AfterSep = 0) THEN
          StrInt = StrInt || SUBSTRING(StrValue FROM 1 FOR 1);
        ELSE IF (DecCount >= Decimals) THEN
          BREAK;
        ELSE
        BEGIN
          StrFrac = StrFrac || SUBSTRING(StrValue FROM 1 FOR 1);
          DecCount = DecCount + 1;
        END
      END
      StrValue = SUBSTRING(StrValue FROM 2 FOR 50);
--      SUSPEND;
    END
    Result = StrInt || '.' || StrFrac;
  END
  SUSPEND;
END^

SET TERM ; ^

Depois pois está aqui que vai gerar o digito verificador.
SET TERM ^ ;

create or alter procedure MODULO11 (
    NUMERO integer)
returns (
    DIGITO integer)
as
declare variable TXTNUMERO varchar(6);
declare variable I integer;
declare variable TOTAL integer;
declare variable DIG integer;
begin
 txtnumero = numero;
 txtnumero = substring(cast( 1000000 + cast(numero as integer) as char(7))
from 2 for 6);
 total = 0;
 DIG = 0;
 i = 1;

  while (i <= 6) do
    begin
      total = total + cast(substring(txtnumero from :i for 1) as
integer)*(8-i);
     i = i + 1;
    end
      if (total <= 11) then
        digito = 11-total;
      else
        begin
          execute procedure SP_Trunc(total/11, 0) returning_values : dig;
           digito = dig;
          digito = (total -(11*digito));
          digito = 11-digito;
          if (digito >= 10) then
             digito = 0;
        end
  suspend;
end^

SET TERM ; ^

/* Following GRANT statetements are generated automatically */

GRANT EXECUTE ON PROCEDURE SP_TRUNC TO PROCEDURE MODULO11;

Depois que você "cadastrar" as procedures, você usa esse exemplo
select modulo11.digito from modulo11(1)
Ou seja passo o numero 1 (um) para a procedure e ela me retornará 9 (nove).
select modulo11.digito from modulo11(2)
o resultado será 7 (sete), e assim por diante.
Espero ter lhe ajudado.
Atenciosamente,

Flávio Divino

Em 10 de junho de 2015 23:21, Walter R. Ojeda Valiente <
sistemas2000profesional em gmail.com> escreveu:

> Si quieres aprender sobre los triggers, puedes leer los siguientes
> artículos:
>
> https://firebird21.wordpress.com/2013/03/17/entendiendo-a-los-triggers/
>
> https://firebird21.wordpress.com/2014/03/14/escribiendo-un-trigger/
>
> Saludos.
>
> Walter.
>
> 2015-06-08 9:46 GMT-04:00 Fabio Cardoso <fabio em alcanceweb.com.br>:
>
> > Olá Sandro,
> >
> > Eu concordo com a primeira saída, criar uma trigger. Porém, não sei como
> > fazer isso, estou em busca de material na internet pra aprender, talvez
> > você possa me dar uma dica da solução do problema.
> >
> > Boa semana.
> >
> > att,
> > Fabio
> >
> >
> > On 08/06/2015 09:24, Sandro Marcelo Pascoal wrote:
> >
> >> Fábio.
> >> Vejo 2 saídas para isso.
> >> 1) Vc cria um trigger para executar o código que calcula do DV
> (recomendo
> >> essa).
> >> 2) Vc cria uma dll com a função de cálculo do DV e usar ela no BD.
> >>
> >> Com relação a usar o generator dentro do trigger/procedure, é simples.
> Vc
> >> usaria CODIGO = GEN_ID(NOME_DO_GEN, 1) e depois faria o cálculo do DV
> >> usando a variável CODIGO.
> >>
> >> Não tenho certeza se é isso que você precisa. Talvez não tenha
> entendido.
> >>
> >> Sandro
> >>
> >> On 06/06/2015 16:56, Fabio Cardoso wrote:
> >>
> >>> Amigos,
> >>>
> >>> Estou criando uma tabela de clientes com o gerador automático de código
> >>> para o campo CLIENTE_ID. O meu caso é que, em vez de usar o gerador
> padrão
> >>> do firebird, onde ele gera o código sequencial (1, 2, 3,.....), eu
> quero
> >>> gerar esse código sequencial adicionando um dígito verificador para
> ele.
> >>>
> >>> Assim, quando eu cadastrar três clientes, em vez de ficar assim
> >>> CLIENTE_ID    -     CLIENTE_NOME
> >>> 1    FABIO
> >>> 2     JOÃO
> >>> 3     CARLOS
> >>>
> >>> Ficaria assim:
> >>> 19    FABIO
> >>> 27    JOAO
> >>> 35    CARLOS
> >>>
> >>> Onde, o código é composto do 1, que é o sequencial + 9, que é o dígito
> >>> verificador desse 1. Eu baixei um código que calcula esse dígito
> >>> verificador no Delphi, mas gostaria de fazer um generator do firebird
> pra
> >>> realizar essa tarefa:
> >>>
> >>> function DvModulo11 ( str: String ): Char;
> >>> var soma, fator, i: Integer;
> >>>
> >>>   function chInt ( ch: Char ): ShortInt;
> >>>   begin
> >>>     Result := Ord ( ch ) - Ord ( '0' );
> >>>   end;
> >>>
> >>>   function intCh ( int: ShortInt ): Char;
> >>>   begin
> >>>     Result := Chr ( int + Ord ( '0' ) );
> >>>   end;
> >>>
> >>> begin
> >>>   soma := 0;
> >>>   fator := 2;
> >>>   for i := Length ( str ) downto 1 do
> >>>   begin
> >>>     soma := soma + chInt ( str[i] ) * fator;
> >>>     Inc ( fator );
> >>>     if fator = 10 then
> >>>     fator := 2;
> >>>   end;
> >>>   soma := 11 - ( soma mod 11 );
> >>>   if soma >= 10 then
> >>>     Result := '1'
> >>>   else
> >>>   Result := intCh ( soma );
> >>> end;
> >>>
> >>>
> >>> um abraço,
> >>> Fabio.
> >>>
> >>> ---
> >>> Este email foi escaneado pelo Avast antivírus.
> >>> https://www.avast.com/antivirus
> >>>
> >>>
> >>> ______________________________________________
> >>> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> >>> Para saber como gerenciar/excluir seu cadastro na lista, use:
> >>> http://www.firebase.com.br/fb/artigo.php?id=1107
> >>> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
> >>>
> >>>
> >>
> >>
> >
> > ---
> > Este email foi escaneado pelo Avast antivírus.
> > https://www.avast.com/antivirus
> >
> >
> > ______________________________________________
> > FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> > Para saber como gerenciar/excluir seu cadastro na lista, use:
> > http://www.firebase.com.br/fb/artigo.php?id=1107
> > Para consultar mensagens antigas: http://firebase.com.br/pesquisa
> >
> ______________________________________________
> FireBase-BR (www.firebase.com.br) - Hospedado em www.locador.com.br
> Para saber como gerenciar/excluir seu cadastro na lista, use:
> http://www.firebase.com.br/fb/artigo.php?id=1107
> Para consultar mensagens antigas: http://firebase.com.br/pesquisa
>



Mais detalhes sobre a lista de discussão lista