Função extenso() no MySQL

Forum sobre SQL.

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

o que estou convertendo:

Código: Selecionar todos


FUNCTION ExtensoDolar( nValor )

   LOCAL cTxt

   cTxt := Extenso( nValor )
   cTxt := StrTran( cTxt, "REAIS", "DOLARES" )
   cTxt := StrTran( cTxt, "REAL", "DOLAR" )

   RETURN cTxt

FUNCTION Extenso( xValue, xFull )

   LOCAL cTxt := ""

   hb_Default( @xFull, .F. )

   IF ValType( xValue ) == "N"
      cTxt := ze_ExtensoDinheiro( xValue )
   ELSEIF ValType( xValue ) == "D"
      IF ! xFull
         cTxt := StrZero( Day( xValue ), 2 ) + " DE " + ze_ExtensoMes( xValue ) + " DE " + StrZero( Year( xValue ), 4 )
      ELSE
         cTxt := ze_ExtensoNumero( Day( xValue ) )
         cTxt += " DE " + ze_ExtensoMes( xValue ) + " DE "
         cTxt += ze_ExtensoNumero( Year( xValue ) )
         DO WHILE Space(2) $ cTxt
            cTxt := StrTran( cTxt, Space(2), Space(1) )
         ENDDO
      ENDIF
   ENDIF

   RETURN cTxt

FUNCTION ze_ExtensoDinheiro( nValor )

   LOCAL cTxt := "", cStrValor, nInteiro, nDecimal

   nValor    := Abs( nValor )
   cStrValor := Str( nValor, 18, 2 )
   nInteiro  := Val( Substr( cStrValor, 1, At( ".", cStrValor ) - 1 ) )
   nDecimal  := Val( Substr( cStrValor, At( ".", cStrValor ) + 1 ) )
   IF nInteiro != 0 .OR. nDecimal == 0
      cTxt += ze_ExtensoNumero( nInteiro ) + " " + iif( nInteiro == 1, "REAL", "REAIS" )
   ENDIF
   IF nDecimal != 0
      IF nInteiro != 0
         cTxt += " E "
      ENDIF
      cTxt += ze_ExtensoNumero( nDecimal ) + " " + iif( nDecimal == 1, "CENTAVO", "CENTAVOS" )
   ENDIF

   RETURN cTxt

STATIC FUNCTION ze_ExtensoNumero( nValor, nGrupo )

   LOCAL cTxt := "", cStrValor, nCentena, nResto, cTxtGrupo := "", lNegativo
   LOCAL aList := { "", "MIL", "MILHAO", "BILHAO", "TRILHAO", "QUATRILHAO", ;
      "QUINTILHAO", "SEPTILHAO", "OCTILHAO", "NONILHAO", "DECILHAO" }

   hb_Default( @nGrupo, 1 )
   lNegativo := ( nValor < 0 )
   nValor    := Abs( nValor )
   cStrValor := StrZero( nValor, 16 )
   nCentena  := Val( Right( cStrValor, 3 ) )
   nResto    := Val( Substr( cStrValor, 1, Len( cStrValor ) - 3 ) )
   IF nCentena != 0
      IF nCentena > 0
         cTxtGrupo := aList[ nGrupo ]
         IF nCentena > 1
            cTxtGrupo := StrTran( cTxtGrupo, "LHAO", "LHOES" )
         ENDIF
      ENDIF
      cTxt := ze_ExtensoCentena( nCentena ) + " " + cTxtGrupo
   ENDIF
   IF nResto != 0 .AND. nGrupo < Len( aList )
      cTxt := ze_ExtensoNumero( nResto, nGrupo + 1 ) + " E " + cTxt
   ENDIF
   IF nGrupo == 1
      IF nValor == 0
         cTxt := "ZERO"
      ENDIF
      cTxt := iif( lNegativo, "*NEGATIVO* ", "" ) + AllTrim( cTxt )
   ENDIF

   RETURN cTxt

STATIC FUNCTION ze_ExtensoUnidade( nValor )

   LOCAL aList := { "UM", "DOIS", "TRES", "QUATRO", "CINCO", "SEIS", ;
      "SETE", "OITO", "NOVE", "DEZ", "ONZE", "DOZE", "TREZE", ;
      "QUATORZE", "QUINZE", "DEZESSEIS", "DEZESSETE", "DEZOITO", ;
      "DEZENOVE" }

   RETURN aList[ nValor ]

STATIC FUNCTION ze_ExtensoDezena( nValor )

   LOCAL aList := { "DEZ", "VINTE", "TRINTA", "QUARENTA", "CINQUENTA", "SESSENTA", ;
      "SETENTA", "OITENTA", "NOVENTA" }
   LOCAL cTxt := "", nDezena, nUnidade

   IF nValor > 0
      nDezena := Int( nValor / 10 )
      nUnidade := Mod( nValor, 10 )
      IF nValor < 20
         cTxt += ze_ExtensoUnidade( nValor )
      ELSE
         cTxt += aList[ nDezena ]
         IF nUnidade != 0
            cTxt += " E " + ze_ExtensoUnidade( nUnidade )
         ENDIF
      ENDIF
   ENDIF

   RETURN cTxt

STATIC FUNCTION ze_ExtensoCentena( nValor )

   LOCAL aList := { "CENTO", "DUZENTOS", "TREZENTOS", "QUATROCENTOS", ;
      "QUINHENTOS", "SEISCENTOS", "SETECENTOS", "OITOCENTOS", ;
      "NOVECENTOS" }
   LOCAL nCentena, nDezena, cTxt := ""

   nCentena := Int( nValor / 100 )
   nDezena  := Mod( nValor, 100 )
   IF nValor > 0
      IF nCentena == 1 .AND. nDezena == 0
         cTxt += "CEM"
      ELSE
         IF nCentena != 0
            cTxt += aList[ nCentena ]
         ENDIF
         IF nDezena != 0
            IF nCentena != 0
               cTxt += " E "
            ENDIF
            cTxt += ze_ExtensoDezena( nDezena )
         ENDIF
      ENDIF
   ENDIF

   RETURN cTxt

STATIC FUNCTION ze_ExtensoMes( xMes )

   LOCAL cNomeMes := ""
   LOCAL aList := { "JANEIRO", "FEVEREIRO", "MARCO", "ABRIL", "MAIO", "JUNHO", "JULHO", ;
      "AGOSTO", "SETEMBRO", "OUTUBRO", "NOVEMBRO", "DEZEMBRO" }

   IF ValType( xMes ) == "D"
      xMes := Month( xMes )
   ENDIF
   DO WHILE xMes > 12
      xMes -= 12
   ENDDO
   IF xMes > 0
      cNomeMes := aList[ xMes ]
   ENDIF

   RETURN cNomeMes

STATIC FUNCTION ze_ExtensoSemana( dData )

   LOCAL aList := { "", "DOMINGO", "SEGUNDA", "TERCA", "QUARTA", "QUINTA", "SEXTA", "SABADO" }

   RETURN aList[ Dow( dData ) + 1 ]
Faltam estas duas:

Código: Selecionar todos

FUNCTION ze_ExtensoDinheiro( nValor )

   LOCAL cTxt := "", cStrValor, nInteiro, nDecimal

   nValor    := Abs( nValor )
   cStrValor := Str( nValor, 18, 2 )
   nInteiro  := Val( Substr( cStrValor, 1, At( ".", cStrValor ) - 1 ) )
   nDecimal  := Val( Substr( cStrValor, At( ".", cStrValor ) + 1 ) )
   IF nInteiro != 0 .OR. nDecimal == 0
      cTxt += ze_ExtensoNumero( nInteiro ) + " " + iif( nInteiro == 1, "REAL", "REAIS" )
   ENDIF
   IF nDecimal != 0
      IF nInteiro != 0
         cTxt += " E "
      ENDIF
      cTxt += ze_ExtensoNumero( nDecimal ) + " " + iif( nDecimal == 1, "CENTAVO", "CENTAVOS" )
   ENDIF

   RETURN cTxt

STATIC FUNCTION ze_ExtensoNumero( nValor, nGrupo )

   LOCAL cTxt := "", cStrValor, nCentena, nResto, cTxtGrupo := "", lNegativo
   LOCAL aList := { "", "MIL", "MILHAO", "BILHAO", "TRILHAO", "QUATRILHAO", ;
      "QUINTILHAO", "SEPTILHAO", "OCTILHAO", "NONILHAO", "DECILHAO" }

   hb_Default( @nGrupo, 1 )
   lNegativo := ( nValor < 0 )
   nValor    := Abs( nValor )
   cStrValor := StrZero( nValor, 16 )
   nCentena  := Val( Right( cStrValor, 3 ) )
   nResto    := Val( Substr( cStrValor, 1, Len( cStrValor ) - 3 ) )
   IF nCentena != 0
      IF nCentena > 0
         cTxtGrupo := aList[ nGrupo ]
         IF nCentena > 1
            cTxtGrupo := StrTran( cTxtGrupo, "LHAO", "LHOES" )
         ENDIF
      ENDIF
      cTxt := ze_ExtensoCentena( nCentena ) + " " + cTxtGrupo
   ENDIF
   IF nResto != 0 .AND. nGrupo < Len( aList )
      cTxt := ze_ExtensoNumero( nResto, nGrupo + 1 ) + " E " + cTxt
   ENDIF
   IF nGrupo == 1
      IF nValor == 0
         cTxt := "ZERO"
      ENDIF
      cTxt := iif( lNegativo, "*NEGATIVO* ", "" ) + AllTrim( cTxt )
   ENDIF

   RETURN cTxt
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Me surgiu uma dúvida:

E no Linux?
Nome de função é case-sensitive?
Vou ter que usar exatamente como escrevi?
Ou tanto faz maiúscula/minúscula?
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

recursive.png
Que pena, não tem recursividade.

Ia chamando a própria rotina, a cada grupo de três números, até acabar.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

extenso.png
Ainda alterando pra LOOP, ao invés de recursividade.

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoNumero`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500) DEFAULT '';
DECLARE nGrupo INT DEFAULT 0;
DECLARE nValGrupo DECIMAL(15,0) ;
DECLARE nValResto DECIMAL(15,0) ;
DECLARE cstrvalor VARCHAR(20);
DECLARE cTxtGrupo VARCHAR(20);

if nvalor = 0 then
   RETURN '*ZERO*';
END if ;

SET cstrvalor = LPAD( ABS( nValor ), 18, '0' );
set nGrupo = 19;

LOOP_GRUPOS: LOOP

   set nGrupo = nGrupo - 3;
   if nGrupo < 0 then
      leave LOOP_GRUPOS;
   END if;

   SET cTxtGrupo = '';
   SET nValGrupo = CAST( SUBSTR( cStrValor, nGrupo, 3 ) AS INT );

/*   SET nValResto = CAST( SUBSTR( cstrvalor, nGrupo * 3 ) AS DECIMAL(15,0)); */
   if nValGrupo > 0 then 
      set cTxtGrupo = (
      case
      when nGrupo = 16 then ''
      when nGrupo = 13 then 'MIL'
      when nGrupo = 10 then 'MILHAO'
      when nGrupo = 7 then 'BILHAO'   
      when nGrupo = 3 then 'TRILHAO'
      when nGrupo = 1 then 'QUATRILHAO'
      /*when nValGrupo = 7 then 'QUINTILHAO'
      when nValGrupo = 8 then 'SEPTILHAO'
      when nValGrupo = 9 then 'OCTILHAO'
      when nValGrupo = 10 then 'NONILHAO'
      when nValGrupo = 11 then 'DECILHAO'
      */
      ELSE '' 
      END );
      set ctxt = CONCAT( ze_ExtensoCentena( nValGrupo ), ' ', cTxtGrupo, ' E ', cTxt );
   END if;
/*
   if nvalresto != 0 then
      SET ctxt = CONCAT( ze_ExtensoNumero( nValResto, nGrupo + 1 ), ' E ', cTxt );
   end if;
*/
   END LOOP LOOP_GRUPOS;

RETURN cTxt;
END
Como eu disse, essa minha rotina ficou interessante.
As anteriores fazem o extenso do grupo de centena.
Esta aqui apenas pega de 3 em 3, e acrescenta conforme o caso, mil, milhão, bilhão, etc.

Isso fecha o ciclo de um valor por extenso.

No caso de dinheiro, é repetir a rotina para a parte inteira com a palavra REAIS, e para a parte decimal com CENTAVOS.
plural ou singular, basta testar se é 1 ou maior que 1.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

extenso.png
Chegando lá

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoNumero`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500) DEFAULT '';
DECLARE nGrupo INT DEFAULT 0;
DECLARE nValGrupo DECIMAL(15,0) ;
DECLARE nValResto DECIMAL(15,0) ;
DECLARE cstrvalor VARCHAR(20);
DECLARE cTxtGrupo VARCHAR(20);
declare ctxtthis VARCHAR(500);

if nvalor = 0 then
   RETURN '*ZERO*';
END if ;

SET cstrvalor = LPAD( ABS( nValor ), 18, '0' );
set nGrupo = 0;

LOOP_GRUPOS: LOOP

   set nGrupo = nGrupo + 1;
   if nGrupo > 6 then
      leave LOOP_GRUPOS;
   END if;

   SET cTxtGrupo = '';
   SET ctxtthis = '';
   SET nValGrupo = CAST( SUBSTR( cStrValor, ( nGrupo * 3 ) - 2, 3 ) AS INT );
   if length( cstrvalor ) <= ngrupo * 3 + 4 then
      set nValResto =0;
   ELSE   
      SET nvalresto = CAST( SUBSTR( cstrvalor, ( nGrupo * 3 ) + 1, 3 ) AS DECIMAL(15,0) );
   END if;
    if nValGrupo > 0 then 
      set cTxtGrupo = (
      case
      when nGrupo = 6 then ''
      when nGrupo = 5 then 'MIL'
      when nGrupo = 4 then 'MILHAO'
      when nGrupo = 3 then 'BILHAO'   
      when nGrupo = 2 then 'TRILHAO'
      when nGrupo = 1 then 'QUATRILHAO'
      when nGrupo = 0 then 'QUINTILHAO'
      when nGrupo = 0 then 'SEPTILHAO'
      when nGrupo = 0 then 'OCTILHAO'
      when nGrupo = 0 then 'NONILHAO'
      when nGrupo = 0 then 'DECILHAO'
      ELSE '' 
      END );
      if nvalgrupo > 1 then
         set cTxtGrupo = REPLACE( ctxtgrupo, 'AO', 'OES' );
      END if ;
      set ctxt = CONCAT( cTxt, ' ',ze_ExtensoCentena( nValGrupo ), ' ', cTxtGrupo );
   END if;
   /* if nValResto != 0 then
	   set cTxt = CONCAT( cTxt, ' E ' );
   END if; */
   END LOOP LOOP_GRUPOS;

RETURN cTxt;
END
ilhão/ilhões

Código: Selecionar todos

      if nvalgrupo > 1 then
         set cTxtGrupo = REPLACE( ctxtgrupo, 'AO', 'OES' );
      END if ;
Só pra lembrar:
extenso2.png
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

extenso.png

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_Extenso`(
	`nValor` DECIMAL(15,2)
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500) DEFAULT '';
DECLARE nInteiro DECIMAL(15,0);
DECLARE ndecimal INT;

SET nInteiro = FLOOR( nValor );
SET ndecimal = ( nvalor - ninteiro ) * 100;
IF ninteiro != 0 then
   SET ctxt = CONCAT( cTxt, ze_ExtensoNumero( nInteiro ), ' ', if( nInteiro > 1, 'REAIS', 'REAL' ) );
END if;
if nInteiro != 0 AND ndecimal != 0 then   
   SET ctxt = CONCAT( cTxt, ' E  ' );
END if;
if ndecimal != 0 then
   SET ctxt = CONCAT( ctxt, ze_ExtensoNumero( ndecimal ), ' ', if( ndecimal > 1, 'CENTAVOS', 'CENTAVO' ) );
END if;   
RETURN cTxt;
END
Agora só ajustes de " E ".
O segundo está certo, porque NÃO é HUM REAL, e sim vários REAIS.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

extenso.png
Agora talvez aumentar o limite ao máximo.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Rotinas:
Extenso de 1 a 19

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoUnidade`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500);
SET cTxt := (
case
when nvalor = 1 then 'HUM'
when nvalor = 2 then 'DOIS'
when nvalor = 3 then 'TRES'
when nvalor = 4 then 'QUATRO'
when nvalor = 5 then 'CINCO'
when nvalor = 6 then 'SEIS'
when nvalor = 7 then 'SETE'
when nvalor = 8 then 'OITO'
when nvalor = 9 then 'NOVE'
when nvalor = 10 then 'DEZ'
when nvalor = 11 then 'ONZE'
when nvalor = 12 then 'DOZE'
when nvalor = 13 then 'TREZE'
when nvalor = 14 then 'QUATORZE'
when nvalor = 15 then 'QUINZE'
when nvalor = 16 then 'DEZESSEIS'
when nvalor = 17 then 'DEZESSETE'
when nvalor = 18 then 'DEZOITO'
when nvalor = 19 then 'DEZENOVE'
ELSE ''
END );
RETURN cTxt;
END
extenso de 1 a 99, que faz uso da anterior

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoDezena`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500);
DECLARE ndezena INT;
DECLARE nunidade INT;
SET ctxt = '';
if nvalor > 0 then 
   if nvalor < 20 then
      set cTxt = ze_ExtensoUnidade( nValor );
   else
      SET ndezena = floor( nvalor / 10 );
      SET nunidade = nvalor - ( ndezena * 10 );
      set cTxt = (
      case 
      when ndezena = 2 then 'VINTE'
      when ndezena = 3 then 'TRINTA'
      when ndezena = 4 then 'QUARENTA'   
      when ndezena = 5 then 'CINQUENTA'
      when ndezena = 6 then 'SESSENTA'
      when ndezena = 7 then 'SETENTA'
      when ndezena = 8 then 'OITENTA'
      when ndezena = 9 then 'NOVENTA'
      ELSE '' 
      END );
      if nunidade != 0 then
         set cTxt = CONCAT( ctxt, ' E ', ze_ExtensoUnidade( nUnidade ) );
      END if ;
   END if;
END if   ;
RETURN cTxt;
END
extenso de 1 a 999, que faz uso das anteriores

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoCentena`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500);
DECLARE ncentena INT;
DECLARE ndezena INT;
SET ctxt = '';
if nValor > 0 then 
   if nValor = 100 then
      set cTxt = 'CEM';
   else
      SET nCentena = floor( nValor / 100 );
      SET nDezena = nValor - ( nCentena * 100 );
	   set cTxt = (
	   case 
	   when ncentena = 1 then 'CENTO'
	   when nCentena = 2 then 'DUZENTOS'
	   when nCentena = 3 then 'TREZENTOS'
	   when nCentena = 4 then 'QUATROCENTOS'   
	   when nCentena = 5 then 'QUINHENTOS'
	   when nCentena = 6 then 'SEISSENTOS'
	   when nCentena = 7 then 'SETECENTOS'
	   when nCentena = 8 then 'OITOCENTOS'
	   when nCentena = 9 then 'NOVECENTOS'
		ELSE '' 
		END );
	   if nDezena != 0 then
		   set cTxt = CONCAT( ctxt, IF( nCentena = 0, '', ' e ' ), ze_ExtensoDezena( nDezena ) );
   	END if ;
	END if;
END if	;
RETURN cTxt;
END
extenso de qualquer número inteiro, que faz uso das anteriores

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_ExtensoNumero`(
	`nValor` INT
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500) DEFAULT '';
DECLARE nGrupo INT DEFAULT 0;
DECLARE nValGrupo DECIMAL(15,0) ;
DECLARE nValResto DECIMAL(15,0) ;
DECLARE cstrvalor VARCHAR(20);
DECLARE cTxtGrupo VARCHAR(20);
declare ctxtthis VARCHAR(500);

if nvalor = 0 then
   RETURN '*ZERO*';
END if ;

SET cstrvalor = LPAD( ABS( nValor ), 18, '0' );
set nGrupo = 0;

LOOP_GRUPOS: LOOP

   set nGrupo = nGrupo + 1;
   if nGrupo > 6 then
      leave LOOP_GRUPOS;
   END if;

   SET cTxtGrupo = '';
   SET ctxtthis = '';
   SET nValGrupo = CAST( SUBSTR( cStrValor, ( nGrupo * 3 ) - 2, 3 ) AS INT );
   if length( cstrvalor ) <= ngrupo * 3 + 4 then
      set nValResto =0;
   ELSE   
      SET nvalresto = CAST( SUBSTR( cstrvalor, ( nGrupo * 3 ) + 1, 3 ) AS DECIMAL(15,0) );
   END if;
    if nValGrupo > 0 then 
      set cTxtGrupo = (
      case
      when nGrupo = 6 then ''
      when nGrupo = 5 then 'MIL'
      when nGrupo = 4 then 'MILHAO'
      when nGrupo = 3 then 'BILHAO'   
      when nGrupo = 2 then 'TRILHAO'
      when nGrupo = 1 then 'QUATRILHAO'
      when nGrupo = 0 then 'QUINTILHAO'
      when nGrupo = 0 then 'SEPTILHAO'
      when nGrupo = 0 then 'OCTILHAO'
      when nGrupo = 0 then 'NONILHAO'
      when nGrupo = 0 then 'DECILHAO'
      ELSE '' 
      END );
      if nvalgrupo > 1 then
         set cTxtGrupo = REPLACE( ctxtgrupo, 'AO', 'OES' );
      END if ;
      set ctxt = CONCAT( cTxt, if( LENGTH( cTxt ) = 0, ' ',' E  '), ze_ExtensoCentena( nValGrupo ), ' ', cTxtGrupo );
   END if;
   /* if nValResto != 0 then
	   set cTxt = CONCAT( cTxt, ' E ' );
   END if; */
   END LOOP LOOP_GRUPOS;

RETURN cTxt;
END
e extenso de valor de moeda, que faz uso das anteriores.

Código: Selecionar todos

CREATE DEFINER=`jpatecnologia`@`%` FUNCTION `ze_Extenso`(
	`nValor` DECIMAL(15,2)
)
RETURNS varchar(500) CHARSET latin1
LANGUAGE SQL
DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE cTxt VARCHAR(500) DEFAULT '';
DECLARE nInteiro DECIMAL(15,0);
DECLARE ndecimal INT;

SET nInteiro = FLOOR( nValor );
SET ndecimal = ( nvalor - ninteiro ) * 100;
IF ninteiro != 0 then
   SET ctxt = CONCAT( cTxt, ze_ExtensoNumero( nInteiro ), ' ', if( nInteiro > 1, 'REAIS', 'REAL' ) );
END if;
if nInteiro != 0 AND ndecimal != 0 then   
   SET ctxt = CONCAT( cTxt, ' E  ' );
END if;
if ndecimal != 0 then
   SET ctxt = CONCAT( ctxt, ze_ExtensoNumero( ndecimal ), ' ', if( ndecimal > 1, 'CENTAVOS', 'CENTAVO' ) );
END if;
set cTxt = REPLACE( cTxt, 'ILHAO REAIS', 'ILHAO DE REAIS' );
set ctxt = REPLACE( cTxt, 'ILHOES REAIS', 'ILHOES DE REAIS' );
RETURN cTxt;
END
Apanhei com o ponto e vírgula (;).
Mas precisa nos cálculos e também nos endif, porque quase sempre o próximo cálculo depende de terminar o endif anterior.
Isso confunde, acaba sendo trabalhoso sem uma ferramenta extra.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Agora a parte péssima:

fiz backup das functions, mas não aceita restaurar, sempre dá erro.

Em outras palavras:
estão na base e funcionam.
Mas o o comando que o HeidiSQL mostra pra criação não funciona.
Não adianta fazer backup.
Os testes foram alterando direto pelo HeidiSQL.

Sei lá....
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Correção da informação:

No MariaDB funcionando ok, backup/restore no MariaDB ok.
O problema é carregar as mesmas funções no MySQL 5.6.
Tentar identificar o que precisa ser diferente pra funcionar no MySQL.
Nem todas foram "rejeitadas" pelo MySQL.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Aproveitando:

O único lado ruim de usar MariaDB que estou vendo é esse daí:
Se nos clientes tem MySQL, mas eu testar apenas no MariaDB, corre esse risco de não funcionar nos clientes.

Nem está diretamente relacionado a MariaDB.
Uma versão mais nova do MySQL pode ter novos recursos que não existiam antes, então tenho que me limitar aos recursos dos "meus servidores".

Mesmo o MariaDB funcionando perfeito, vou ter que testar isso no MySQL, porque não vai funcionar nos clientes, e nem no meu servidor da internet, que é instalado pelo provedor, e não tenho opção de escolher/trocar.

O extenso que estava pronto, não está mais, porque não funciona no MySQL que uso na internet.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

erroextenso.png
Ainda tem algo errado - para o MySQL 5.6

NOTA: APESAR DE MOSTRAR LENGHT, É LENGTH, MAS DÁ ERRO DO MESMO JEITO.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Achei

Código: Selecionar todos

DECLARE nValGrupo DECIMAL(15,0) ;
...
SET nValGrupo = CAST( SUBSTR( cStrValor, ( nGrupo * 3 ) - 2, 3 ) AS INT ); 
No MariaDB não tem problema nisso, mas no MySQL....

Código: Selecionar todos

SET nValGrupo = CAST( SUBSTR( cStrValor, ( nGrupo * 3 ) - 2, 3 ) AS DECIMAL(5,0) ); 
O MySQL avisou... era próximo do INT....
Só não mostrou o INT.... kkkkk
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

extensomysql.png
Aqui no MySQL 5.6
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"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 do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Função extenso() no MySQL

Mensagem por JoséQuintas »

Agora falta resolver uma coisa:
Como executar isso?
Pelo HeidiSQL os comandos funcionam pra criação de função, mas executando via Harbour não.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder