Ver Mensaje Individual
  #13  
Antiguo 03-10-2011
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 947
Reputación: 25
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Cita:
Empezado por guillotmarc Ver Mensaje
Te sería mucho más cómodo traducir este código Delphi a Transact-SQL y así ponerlo en un procedimiento almacenado.

De esta forma no te tendrás que preocupar de UDF's, lo tendrás siempre disponible en tu base de datos. No te tendrás que preocupar de distribuirlo en nuevas instalaciones, de si tu servidor corre en Windows o en Linux, de si será compatible con nuevas versiones de Firebird, etc. ... ...

Claro que esa traducción no es trivial, pero las ventajas sobre una UDF valen la pena.
Tome tu idea, y comenze a buscar en la red algun codigo que realizara el trabajo de traducir numero a palabras. (Para que inventar la rueda ) ..y encontre esto Script de Oracle, especificamente este enlace Numeros a Palabras


Despues de analizar me puse manos a la obra y realizar la traduccion para Firebird...

La estuve probando (Firebird 2.5) y al parecer funciona bien, eso si que hay que seguir chequeando...Les dejo el script para la creacion de los procedimientos almacenados.

Cita:
/**************************************************************************************************** ******/
/* */
/* Procedure: NumberToWords */
/* Description: This package provides a function NumberToWords converting numbers to their */
/* English equivalent and returns it as a string. */
/* */
/* Version: 1.0.0 */
/* */
/* Required: Oracle Server Version 7.3 or higher. */
/* */
/* Example: */
/* */
/* SELECT NumberToWords.NumberToWords(1234567890) FROM DUAL; */
/* */
/* Written by: Material Dreams */
/* EMail: [email protected] */
/* WWW: http://www.materialdreams.com/oracle */
/* */
/* License: This script can be freely distributed as long as this header will not be removed and */
/* improvements and changes to this script will be reported to the author. */
/* */
/* Copyright (c) 1995-2004 by Material Dreams. All Rights Reserved. */
/* */
/**************************************************************************************************** ******/

/*
Traduccion a Firebird: Christian Loayza

SELECT * FROM NUMBER_EXECUTE(125425)
*/


SET TERM ^ ;
create procedure NUMBER_MILES (
THEVALUE integer)
returns (
ARESULT varchar(20))
as
begin
AResult='';
AResult=IIF(TheValue=1,' ',AResult);
AResult=IIF(TheValue=2,'mil',AResult);
AResult=IIF(TheValue=3,'millon',AResult);
AResult=IIF(TheValue=4,'billon',AResult);
AResult=IIF(TheValue=5,'trillon',AResult);
AResult=IIF(TheValue=6,'quatrillon',AResult);
AResult=IIF(TheValue=7,'quintillon',AResult);
AResult=IIF(TheValue=8,'sistillon',AResult);
AResult=IIF(TheValue=9,'septillion',AResult);
AResult=IIF(TheValue=10,'octillon',AResult);
AResult=IIF(TheValue=11,'nonillion',AResult);
AResult=IIF(TheValue=12,'decillion',AResult);
AResult=IIF(TheValue=13,'undecillion',AResult);
AResult=IIF(TheValue=14,'duodecillio',AResult);
AResult=IIF(TheValue=15,'tredecillion',AResult);
AResult=IIF(TheValue=16,'quintuordecillion',AResult);
AResult=IIF(TheValue=17,'sexdecillion',AResult);
AResult=IIF(TheValue=18,'septendecillion',AResult);
AResult=IIF(TheValue=19,'octodecillion',AResult);
AResult=IIF(TheValue=20,'novemdecillion',AResult);
AResult=IIF(TheValue=21,'vigintillion',AResult);
AResult=IIF(TheValue=22,'vigintillion',AResult);

end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_NAME (
VALOR integer)
returns (
RESULT varchar(10))
as
begin
SELECT
CASE :Valor
WHEN 01 THEN 'cero'
WHEN 02 THEN 'uno'
WHEN 03 THEN 'dos'
WHEN 04 THEN 'tres'
WHEN 05 THEN 'cuatro'
WHEN 06 THEN 'cinco'
WHEN 07 THEN 'seis'
WHEN 08 THEN 'siete'
WHEN 09 THEN 'ocho'
WHEN 10 THEN 'nueve'
WHEN 11 THEN 'diez'
WHEN 12 THEN 'once'
WHEN 13 THEN 'doce'
WHEN 14 THEN 'trece'
WHEN 15 THEN 'catorce'
WHEN 16 THEN 'quince'
WHEN 17 THEN 'diesiseis'
WHEN 18 THEN 'diesisiete'
WHEN 19 THEN 'diesiocho'
WHEN 20 THEN 'diesinueve'
WHEN 21 THEN iif(MOD(:VALOR, 10)=0,'veinte','veinti')
WHEN 22 THEN 'treinta'
WHEN 23 THEN 'cuarenta'
WHEN 24 THEN 'cincuenta'
WHEN 25 THEN 'sesenta'
WHEN 26 THEN 'setenta'
WHEN 27 THEN 'ochenta'
WHEN 28 THEN 'noventa'
WHEN 29 THEN ''
END as Result
FROM
rdb$database
into :Result;

suspend;
end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_VALUE (
VALOR integer)
returns (
RESULT integer)
as
begin
SELECT
CASE :Valor
WHEN 01 THEN 0
WHEN 02 THEN 1
WHEN 03 THEN 2
WHEN 04 THEN 3
WHEN 05 THEN 4
WHEN 06 THEN 5
WHEN 07 THEN 6
WHEN 08 THEN 7
WHEN 09 THEN 8
WHEN 10 THEN 9
WHEN 11 THEN 10
WHEN 12 THEN 11
WHEN 13 THEN 12
WHEN 14 THEN 13
WHEN 15 THEN 14
WHEN 16 THEN 15
WHEN 17 THEN 16
WHEN 18 THEN 17
WHEN 19 THEN 18
WHEN 20 THEN 19
WHEN 21 THEN 20
WHEN 22 THEN 30
WHEN 23 THEN 40
WHEN 24 THEN 50
WHEN 25 THEN 60
WHEN 26 THEN 70
WHEN 27 THEN 80
WHEN 28 THEN 90
WHEN 29 THEN 999
END as result
FROM
rdb$database
Into :Result;
SUSPEND;

end^

SET TERM ; ^

SET TERM ^ ;
create procedure NUMBER_DECENAS (
THEVALUE integer)
returns (
S varchar(80))
as
declare variable V integer;
declare variable I integer;
declare variable X integer;
declare variable CNAME varchar(10);
BEGIN
v = theValue;
i = 1;
s ='';
EXECUTE PROCEDURE NUMBER_VALUE(i) RETURNING_VALUES :x;
WHILE (x <= v) DO
BEGIN
i = i + 1;
EXECUTE PROCEDURE NUMBER_VALUE(i) RETURNING_VALUES :x;
END

EXECUTE PROCEDURE NUMBER_NAME(i-1) RETURNING_VALUES :cname;
EXECUTE PROCEDURE NUMBER_VALUE(i-1) RETURNING_VALUES :x;
v = v - x;
s=TRIM(cname);

IF (v > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_NAME(v+1) RETURNING_VALUES :cname;
IF (X<>20) THEN
s = s || ' y ' || TRIM(cname);
ELSE
s = s || IIF(s<>'',' ','') || TRIM(cname);
END
SUSPEND;
end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_CENTENAS (
THEVALUE integer)
returns (
S varchar(80))
as
declare variable V integer;
declare variable N integer;
declare variable R integer;
declare variable M integer;
declare variable CNAME varchar(80);
BEGIN
v = theValue;
m = MOD(v, 100);
r = FLOOR(v / 100);
s = '';

IF (r > 0) THEN
BEGIN
s='';
s=IIF(r=1 and m=0,'cien',s);
s=IIF(r=1 and m>1,'ciento',s);
s=IIF(r=2,'doscientos',s);
s=IIF(r=3,'trescientos',s);
s=IIF(r=4,'cuatrocientos',s);
s=IIF(r=5,'quinientos',s);
s=IIF(r=6,'seiscientos',s);
s=IIF(r=7,'setecientos',s);
s=IIF(r=8,'ochocientos',s);
s=IIF(r=9,'novecientos',s);
END

IF (m > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_DECENAS(m) RETURNING_VALUES :cname;
s = s ||IIF(s<>'',' ','')||TRIM(cname);
END
SUSPEND;
END^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_EXECUTE (
THENUMBER integer)
returns (
WORD varchar(255))
as

declare variable TRUE integer;
declare variable FALSE integer;
declare variable VAL integer;
declare variable TRI integer;
declare variable PLACE integer;
declare variable NEG integer;
declare variable TEMP varchar(255);
declare variable PHRASE varchar(255);
declare variable S varchar(80);
begin
True=1; False=0; Tri=0; place=0; neg=0; Word='';
val=TheNumber;

-- check for 0
IF (val = 0) THEN
BEGIN
word = 'zero';
suspend;
exit;
END

-- check for negative int
IF (val < 0) THEN
BEGIN
neg= TRUE;
val= -val;
END

-- what we do now is break it up into sets of three, and add the appropriate denominations to each
WHILE (val > 0) DO
BEGIN
phrase = '';
tri = MOD(val, 1000); -- last tree digits
val = FLOOR(val / 1000); -- base 10 shift by 3
IF (tri > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_CENTENAS(tri) RETURNING_VALUES :s;
phrase = phrase || s;
END

IF ((place > 0) AND (tri > 0)) THEN
begin
EXECUTE PROCEDURE NUMBER_MILES(place+1) RETURNING_VALUES :s;

IF (MOD(Tri, 10)=1 ) THEN
phrase = SUBSTRING(phrase FROM 1 FOR CHAR_LENGTH(TRIM(phrase)))||' '|| s;
ELSE
phrase = phrase ||' '|| s ||IIF(place>=2,'es','');
end
place = place + 1;

-- got the phrase, now put in the string
temp = word;
IF ((val > 0) AND (tri > 0)) THEN
word = ' ' || phrase;
ELSE
word = phrase;

word = word || temp;
END

-- remember that minus sign
IF (neg=True) THEN
word = 'negative ' || word;

SUSPEND;
end
^
SET TERM ; ^


Saludos
Responder Con Cita