La siguiente funcion esta escrita en plpgsql y retorna un cadena de texto correspondiente a un numero que se pasa por parametro, la funcion devuelve hasta un maximo de 999999999,99
Esta funcion la saque de un foro hace un tiempo ya, la tenia en alguna BD de prueba y para no perderla... pues la coloco aqui..
-- DROP FUNCTION f_convnl(numeric);
CREATE OR REPLACE FUNCTION f_convnl(num numeric)
  RETURNS character varying AS
$BODY$
-- Función que devuelve la cadena de texto en castellano que corresponde a un número.
-- Parámetros: número con 2 decimales, máximo 999999999,99.
 
DECLARE 
 d VARCHAR[];
 f VARCHAR[];
 g VARCHAR[];
 numt VARCHAR;
 txt VARCHAR;
 a INTEGER;
 a1 INTEGER;
 a2 INTEGER;
 n INTEGER;
 p INTEGER;
 negativo BOOLEAN;
BEGIN
 -- Máximo 999.999.999,99
 IF num > 999999999.99 THEN
  RETURN '---';
 END IF;
 txt = '';
 d = ARRAY[' un',' dos',' tres',' cuatro',' cinco',' seis',' siete',' ocho',' nueve',' diez',' once',' doce',' trece',' catorce',' quince',
  ' dieciseis',' diecisiete',' dieciocho',' diecinueve',' veinte',' veintiun',' veintidos', ' veintitres', ' veinticuatro', ' veinticinco',
  ' veintiseis',' veintisiete',' veintiocho',' veintinueve'];
 f = ARRAY ['','',' treinta',' cuarenta',' cincuenta',' sesenta',' setenta',' ochenta', ' noventa'];
 g= ARRAY [' ciento',' doscientos',' trescientos',' cuatrocientos',' quinientos',' seiscientos',' setecientos',' ochocientos',' novecientos'];
 numt = LPAD((num::numeric(12,2))::text,12,'0');
 IF strpos(numt,'-') > 0 THEN
    negativo = TRUE;
 ELSE
    negativo = FALSE;
 END IF;
 numt = TRANSLATE(numt,'-','0');
 numt = TRANSLATE(numt,'.,','');
 -- Trato 4 grupos: millones, miles, unidades y decimales
 p = 1;
 FOR i IN 1..4 LOOP
  IF i < 4 THEN
   n = substring(numt::text FROM p FOR 3);
  ELSE
   n = substring(numt::text FROM p FOR 2);
  END IF;
  p = p + 3;
  IF i = 4 THEN
   IF txt = '' THEN
    txt = ' cero';
   END IF;
   IF n > 0 THEN
   -- Empieza con los decimales
    txt = txt || ' con';
   END IF;
  END IF;
  -- Centenas 
  IF n > 99 THEN
   a = substring(n::text FROM 1 FOR 1);
   a1 = substring(n::text FROM 2 FOR 2);
   IF a = 1 THEN
    IF a1 = 0 THEN
     txt = txt || ' cien';
    ELSE
     txt = txt || ' ciento';
    END IF;
   ELSE
    txt = txt || g[a];
   END IF;
  ELSE
   a1 = n;
  END IF;
  -- Decenas
  a = a1;
  IF a > 0 THEN
   IF a < 30 THEN
    IF a = 21 AND (i = 3 OR i = 4) THEN
     txt = txt || ' veintiuno';
    ELSIF n = 1 AND i = 2 THEN
     txt = txt; 
    ELSIF a = 1 AND (i = 3 OR i = 4)THEN
     txt = txt || ' uno';
    ELSE
     txt = txt || d[a];
    END IF;
   ELSE
    a1 = substring(a::text FROM 1 FOR 1);
    a2 = substring(a::text FROM 2 FOR 1);
    IF a2 = 1 AND (i = 3 OR i = 4) THEN
      txt = txt || f[a1] || ' y' || ' uno';
    ELSE
     IF a2 <> 0 THEN
      txt = txt || f[a1] || ' y' || d[a2];
     ELSE
      txt = txt || f[a1];
     END IF;
    END IF;
   END IF;
  END IF;
  IF n > 0 THEN
   IF i = 1 THEN
    IF n = 1 THEN
     txt = txt || ' millón';
    ELSE
     txt = txt || ' millones';
    END IF;
   ELSIF i = 2 THEN
    txt = txt || ' mil';
   END IF;  
  END IF;
 END LOOP;
 txt = LTRIM(txt);
 IF negativo = TRUE THEN
    txt= '-' || txt;
 END IF;
    RETURN txt;
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE
  COST 100;
ALTER FUNCTION f_convnl(numeric) OWNER TO u_test;
 
muy bueno me sirvio de mucho gracias
ResponderEliminar