Clipper On Line • Ver Tópico - Dígito de controle

Dígito de controle

Discussão sobre SQL

Moderador: Moderadores

 

Dígito de controle

Mensagempor JoséQuintas » 03 Jul 2021 21:57

FUNCTION CalculaDigito( cNumero, cModulo )

   LOCAL nFator, nCont, nSoma, nResto, nModulo, cCalculo

   hb_Default( @cModulo, "11" )
   IF Empty( cNumero )
      RETURN ""
   ENDIF
   cCalculo := AllTrim( cNumero )
   nModulo  := Val( cModulo )
   nFator   := 2
   nSoma    := 0
   IF nModulo == 10
      FOR nCont = Len( cCalculo ) To 1 Step -1
         nSoma += Val( Substr( cCalculo, nCont, 1 ) ) * nFator
         nFator += 1
      NEXT
   ELSE
      FOR nCont = Len( cCalculo ) To 1 Step -1
         nSoma += Val( Substr( cCalculo, nCont, 1 ) ) * nFator
         IF nFator == 9
            nFator := 2
         ELSE
            nFator += 1
         ENDIF
      NEXT
   ENDIF
   nResto := 11 - Mod( nSoma, 11 )
   IF nResto > 9
      nResto := 0
   ENDIF
   cCalculo := Str( nResto, 1 )

   RETURN cCalculo


CREATE FUNCTION `ze_CalculaDigito`(
   `cNumero` VARCHAR(30),
   `nModulo` INT(11)
)
RETURNS VARCHAR(1)
BEGIN
   DECLARE nFator INT(11);
   DECLARE nSoma INT(11);
   DECLARE nCont INT(11);
   DECLARE nResto INT(11);

   IF LENGTH( cNumero ) < 1 THEN
      RETURN '';
   END IF;

   SET nFator = 2;
   SET nSoma = 0;
   SET nCont = LENGTH( cNumero );

   IF nModulo = 10 THEN
      WHILE nCont > 0 DO
         SET nSoma = nSoma + ( CAST( SUBSTR( cNumero, nCont, 1 ) AS INTEGER ) * nFator ) ;
         SET nFator = nFator + 1;
         SET nCont = nCont - 1;
      END WHILE;
   ELSE
      WHILE nCont > 0 DO
         SET nSoma = nSoma + ( CAST( SUBSTR( cNumero, nCont, 1 ) AS INTEGER ) * nFator ) ;
         IF nFator = 9 THEN
            SET nFator = 2;
         ELSE
            SET nFator = nFator + 1;
         END IF;
         SET nCont = nCont - 1;
      END WHILE;
   END IF;

   SET nResto = 11 - MOD( nSoma, 11 );
   IF nResto > 9 THEN
      SET nResto = 0;
   END IF;

   RETURN CAST( nResto AS VARCHAR(1) );
END


Em fase de testes ainda.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18113
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1213 vezes

Dígito de controle

Mensagempor JoséQuintas » 04 Jul 2021 18:44

Tá divertido isso.
Rotina de calcular dígito

CREATE FUNCTION `ze_CalculaDigito`(
   `cNumero` VARCHAR(30),
   `nModulo` INT(11)
)
RETURNS varchar(1) CHARSET latin1
BEGIN
   DECLARE nFator INT(11);
   DECLARE nSoma INT(11);
   DECLARE nCont INT(11);
   DECLARE nResto INT(11);

   IF LENGTH( cNumero ) < 1 THEN
      RETURN '';
   END IF;

   SET nFator = 2;
   SET nSoma = 0;
   SET nCont = LENGTH( cNumero );

   IF nModulo = 10 THEN
      WHILE nCont > 0 DO
         SET nSoma = nSoma + ( CAST( SUBSTR( cNumero, nCont, 1 ) AS INTEGER ) * nFator ) ;
         SET nFator = nFator + 1;
         SET nCont = nCont - 1;
      END WHILE;
   ELSE
      WHILE nCont > 0 DO
         SET nSoma = nSoma + ( CAST( SUBSTR( cNumero, nCont, 1 ) AS INTEGER ) * nFator ) ;
         IF nFator = 9 THEN
            SET nFator = 2;
         ELSE
            SET nFator = nFator + 1;
         END IF;
         SET nCont = nCont - 1;
      END WHILE;
   END IF;

   SET nResto = 11 - MOD( nSoma, 11 );
   IF nResto > 9 THEN
      SET nResto = 0;
   END IF;

   RETURN CAST( nResto AS VARCHAR(1) );
END


Rotina de retornar só numeros.
CREATE FUNCTION `ze_SoNumeros`(
   `cValue` VARCHAR(20)
)
RETURNS varchar(20) CHARSET latin1
BEGIN
DECLARE cReturn VARCHAR(20) DEFAULT '';
DECLARE nCont INTEGER DEFAULT 1;
WHILE nCont <= LENGTH( cValue ) DO
   IF SUBSTR( cValue, nCont, 1 ) IN ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
      set creturn = CONCAT( creturn, SUBSTR( cvalue, ncont, 1 ) );
   END if;
   SET ncont = ncont + 1;
END WHILE;
RETURN creturn;
END


Rotina de validar CNPJ

CREATE FUNCTION `ze_ValidCNPJ`(
   `cCnpj` VARCHAR(20)
)
RETURNS int(11)
BEGIN

DECLARE cNumero VARCHAR(20);
DECLARE lOk INTEGER;
SET cNumero = ze_SoNumeros( cCnpj );
IF LENGTH( cNumero ) <> 14 THEN
   RETURN IF( LENGTH( cNumero ) = 0, 1, 0 );
END IF;
SET cNumero = LPAD( cNumero, 14, '0' );
SET cNumero = SUBSTR( cNumero, 1, 12 );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 11 ) );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 11 ) );
SET lOk =  ( Right( cCnpj, 2 ) = Right( cNumero, 2 ) );
IF lOk THEN
   SET cCnpj = CONCAT( SUBSTR( cNumero, 1, 2 ), '.',
               SUBSTR( cNumero, 3, 3 ), '.',
               SUBSTR( cNumero, 6, 3 ), '/',
               SUBSTR( cNumero, 9, 4 ), '-',
               SUBSTR( cNumero, 13, 2 ) );
END IF;

RETURN lOk;

END


Rotina de validar CPF

CREATE FUNCTION `ze_ValidCPF`(
   `cCPF` VARCHAR(20)
)
RETURNS int(11)
BEGIN

DECLARE cNumero VARCHAR(20);
DECLARE lOk INTEGER;
SET cNumero = ze_SoNumeros( CCPF );
IF LENGTH( cNumero ) <> 11 THEN
   RETURN IF( LENGTH( cNumero ) = 0, 1, 0 );
END IF;
SET cNumero = LPAD( cNumero, 11, '0' );
SET cNumero = SUBSTR( cNumero, 1, 9 );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 10 ) );
SET cNumero = CONCAT( cNumero, ze_CalculaDigito( cNumero, 10 ) );
SET lOK = ( RIGHT( cCPF, 2 ) = RIGHT( cNumero, 2 ) );
IF lOK THEN
   SET CCPF = CONCAT(
              SUBSTR( cNumero, 1, 3 ), '.',
              SUBSTR( CNUMERO, 4, 3 ), '.',
              SUBSTR( CNUMERO, 7, 3 ), '-',
              SUBSTR( cNumero, 10, 2 ) );
END IF;

RETURN lOk;

END
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18113
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1213 vezes

Dígito de controle

Mensagempor JoséQuintas » 05 Jul 2021 12:52

Aproveitar pra comentar sobre um erro que cometi durante os testes:
esqueci de dentro do LOOP somar 1

O erro do MySQL foi que a variável não comportava o resultado da operação.
Pode ser interessante conhecer os erros, porque pode acontecer com qualquer um.
E a mensagem com certeza não vai ser igual ao Harbour, que são as mensagens que já conhecemos.

Só não estou gostando de não ter os mesmos recursos do Harbour.
Parece até que estamos voltando ao passado, no tempo de começar a programar, usando recursos mínimos.

Também é ruim não ter um ambiente de testes, ou um modo debug pra acompanhar passo a passo.
E é chato ter que separar CADA rotina em uma função diferente.
Mas... devagar acaba dando certo.

Tudo isso é novidade pra mim, ainda pegando o jeito.
Mas é igual comento com vocês: é começar com as rotinas pequenas, ir se acostumando/revisando, e aos poucos criando rotinas maiores.

Com a validação de CPF e CNPJ, posso, por exemplo, pedir para o MySQL os cadastros irregulares, sem precisar nenhuma checagem pelo programa.
É mais pra ir treinando criar funções.

Mas é como já falei:
Se decidir trocar de linguagem de programação, ou desenvolver pra WEB, ANDROID, etc., basta usar os recursos do MySQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18113
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1213 vezes

Dígito de controle

Mensagempor JoséQuintas » 06 Jul 2021 05:56

MySQL 5.7 é chato, comparado ao Mariadb 10.

Válido no Mariadb:

DECLARE nVar INT(11);
DECLARE nVar INTEGER;
SET x = CAST( '1' AS INTEGER );
SET x = CAST( '1' AS INT );
SET x = CAST( '1' AS SIGNED );


Válido no MySQL 5.7:

DECLARE nVar INT(11);
SET x = CAST( '1' AS SIGNED );


São essas coisas que atrapalham desenvolver no MariaDB e depois instalar no MySQL.

Vou acabar voltando o MySQL 5.7, mas NÃO por problema no MariaDB ou MySQL mais novo, mas pra não ter surpresa nos clientes.

No cliente é sempre a versão mais nova, mas na máquina de desenvolvimento melhor sempre o mais velho de todos os instalados.

Ou......
Começar a pensar em atualizar todos pra última versão do MariaDB.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg, multithread, dbfcdx, ADO+MySql, PNotepad
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar de usuário

JoséQuintas
Membro Master

Membro Master
 
Mensagens: 18113
Data de registro: 26 Fev 2007 11:59
Cidade/Estado: São Paulo-SP
Curtiu: 15 vezes
Mens.Curtidas: 1213 vezes




Retornar para SQL

Quem está online

Usuários vendo este fórum: Nenhum usuário registrado online e 4 visitantes


Ola Amigo, espero que meu site e forum tem lhe beneficiado, com exemplos e dicas de programacao.
Entao divulgue o link da Doacao abaixo para seus amigos e redes sociais ou faça uma doacao para o site forum...
MUITO OBRIGADO PELA SUA DOACAO!
Faça uma doação para o forum
cron
v
Olá visitante, seja bem-vindo ao Fórum Clipper On Line!
Efetue o seu login ou faça o seu Registro