Ver Mensaje Individual
  #2  
Antiguo 29-01-2012
[birmain] birmain is offline
Miembro Premium
 
Registrado: feb 2005
Ubicación: Albacete - España
Posts: 59
Reputación: 22
birmain Va por buen camino
Esta es la solución

Tengo implementado un procedimiento almacenado que hace justamente eso. Admite tres parámetros de entrada:

NUMERO DECIMAL(18,4)
LONGNUM INTEGER,
PREC SMALLINT

y devuelve
RESULTADO VARCHAR(100)

El primero obviamente es el número a formatear, el segundo es la longitud de la cadena resultante, o sea que justifica con espacios a la izquierda hasta completar esa longitud, y el tercero es la precisión decimal con la que se obtendrá la salida.

Ejemplo: 1456.279, 12, 2 daría : '(cuatro espacios)1.456,28'

Este es el código del procedimiento almacenado:

Código SQL [-]
/******************************************************************************/
/***        Funciona en Firebird 2.5.x          ***/
/******************************************************************************/

SET SQL DIALECT 3;

SET NAMES NONE;

SET CLIENTLIB 'C:\Program Files (x86)\Firebird\Firebird_2_5\bin\fbclient.dll'; -- Poner aquí el path del cliente firebird

CREATE DATABASE 'cadena de conexión'
USER 'SYSDBA' PASSWORD 'masterkey'
PAGE_SIZE 8192
DEFAULT CHARACTER SET NONE COLLATION NONE;



SET TERM ^ ; 



/******************************************************************************/
/***                           Stored Procedures                            ***/
/******************************************************************************/

CREATE PROCEDURE IUDF_FORMATO_NUM (
    NUMERO DECIMAL(18,4),
    LONGNUM INTEGER,
    PREC SMALLINT)
RETURNS (
    RESULTADO VARCHAR(100))
AS
BEGIN
  SUSPEND;
END^






SET TERM ; ^



/******************************************************************************/
/***                           Stored Procedures                            ***/
/******************************************************************************/


SET TERM ^ ;

ALTER PROCEDURE IUDF_FORMATO_NUM (
    NUMERO DECIMAL(18,4),
    LONGNUM INTEGER,
    PREC SMALLINT)
RETURNS (
    RESULTADO VARCHAR(100))
AS
declare variable PARTE_ENTERA integer;
declare variable PARTE_DECIMAL integer;
declare variable NUM decimal(18,6);
declare variable NEGATIVO varchar(10);
declare variable NUM_CAD varchar(50);
declare variable POSDEC smallint;
declare variable J integer;
declare variable I integer;
declare variable PARTE_ENTERA_CAD varchar(100);
declare variable PARTE_DECIMAL_CAD varchar(20);
declare variable PARTE_ENTERA_CAD_REV varchar(100);
declare variable COMA varchar(5);
declare variable DECIMAL_CAD varchar(10);
begin
  if (numero < 0) then negativo = '-'; else negativo = '';
  numero = abs(numero);
  coma = ',';


  if (prec > 6) then prec = 6;
  num_cad = cast(numero as varchar(50));
  posdec = position('.' in num_cad);
  if (posdec <> 0) then
  begin
     num_cad = substring(num_cad from posdec+1);
     num_cad = trim(trailing '0' from num_cad);
  end


  parte_entera = floor(numero);
  num = round(numero, prec);
  num = num - parte_entera;
  parte_decimal = cast(num * power(10, prec) as integer);

  decimal_cad = cast(parte_decimal as varchar(10));
  if (char_length(num_cad) > prec) then
  begin
      decimal_cad = rpad(decimal_cad, char_length(num_cad), '0');
      parte_decimal = cast(decimal_cad as integer);
  end


  -- Extracción de la parte entera y decimal
  parte_entera = floor(numero);
  num = round(numero, prec);
  num = num - parte_entera;
  parte_decimal = cast(num * power(10, prec) as integer);
  parte_entera_cad = cast(parte_entera as varchar(100));
  parte_decimal_cad = cast(parte_decimal as varchar(10));

  if (parte_decimal = 0) then parte_decimal_cad = lpad('', prec,  '0');

  parte_entera_cad_rev = '';
  j = char_length(parte_entera_cad);
  i = 0;
  while (j >= 1) do
  begin
     i = i + 1;
     parte_entera_cad_rev = parte_entera_cad_rev || substring(parte_entera_cad from j for 1);
     if ((mod(i, 3)=0) and (j>1)) then parte_entera_cad_rev = parte_entera_cad_rev || '.';
     j = j - 1;
  end
  resultado = negativo || reverse(parte_entera_cad_rev) || coma || parte_decimal_cad;
  resultado = lpad(resultado,  longnum, ' ');
  suspend;
end^



SET TERM ; ^

Última edición por birmain fecha: 29-01-2012 a las 12:09:02.
Responder Con Cita