Olá,
Nesse artigo, mostrarei o uso de uma função que recebe como parâmetro um número real com o objetivo de retornar o número por extenso (monetário), e também uma função na qual se é possível obter o resultado de uma fórmula matemática, onde a mesma pode conter uma chamada para outras fórmulas.
Função extenso em PL/SQLcreate or replace function extenso (valor number) return varchar2 is
extenso varchar2(240);
b1 number(1);
b2 number(1);
b3 number(1);
b4 number(1);
b5 number(1);
b6 number(1);
b7 number(1);
b8 number(1);
b9 number(1);
b10 number(1);
b11 number(1);
b12 number(1);
b13 number(1);
b14 number(1);
l1 varchar2(12);
l2 varchar2(3);
l3 varchar2(9);
l4 varchar2(3);
l5 varchar2(6);
l6 varchar2(8);
l7 varchar2(12);
l8 varchar2(3);
l9 varchar2(9);
l10 varchar2(3);
l11 varchar2(6);
l12 varchar2(8);
l13 varchar2(12);
l14 varchar2(3);
l15 varchar2(9);
l16 varchar2(3);
l17 varchar2(6);
l18 varchar2(8);
l19 varchar2(12);
l20 varchar2(3);
l21 varchar2(9);
l22 varchar2(3);
l23 varchar2(6);
l24 varchar2(16);
l25 varchar2(3);
l26 varchar2(9);
l27 varchar2(3);
l28 varchar2(6);
l29 varchar2(17);
virgula_bi char(3);
virgula_mi char(3);
virgula_mil char(3);
virgula_cr char(3);
valor1 char(14);
-- TABELA DE CENTENAS --
centenas char(108) := ' Cento Duzentos Trezentos'||
'Quatrocentos Quinhentos Seiscentos'||
' Setecentos Oitocentos Novecentos';
-- TABELA DE DEZENAS --
dezenas char(79) := ' Dez Vinte Trinta Quarenta'||
'Cinquenta Sessenta Setenta Oitenta'||
'Noventa';
-- TABELA DE UNIDADES --
unidades char(54) := ' Um Dois TresQuatro Cinco Seis'||
' Sete Oito Nove';
-- TABELA DE UNIDADES DA DEZENA 10 --
unid10 char(81) := ' Onze Doze Treze Quatorze'||
' QuinzeDezesseisDezessete Dezoito'||
' Dezenove';
begin
valor1 := lpad(to_char(valor*100), 14,'0');
b1 := substr(valor1, 1, 1);
b2 := substr(valor1, 2, 1);
b3 := substr(valor1, 3, 1);
b4 := substr(valor1, 4, 1);
b5 := substr(valor1, 5, 1);
b6 := substr(valor1, 6, 1);
b7 := substr(valor1, 7, 1);
b8 := substr(valor1, 8, 1);
b9 := substr(valor1, 9, 1);
b10 := substr(valor1, 10, 1);
b11 := substr(valor1, 11, 1);
b12 := substr(valor1, 12, 1);
b13 := substr(valor1, 13, 1);
b14 := substr(valor1, 14, 1);
if valor != 0 then
if b1 != 0 then
if b1 = 1 then
if b2 = 0 and b3 = 0 then
l5 := 'Cem';
else
l1 := substr(centenas, b1*12-11, 12);
end if;
else
l1 := substr(centenas, b1*12-11, 12);
end if;
end if;
if b2 != 0 then
if b2 = 1 then
if b3 = 0 then
l5 := 'Dez';
else
l3 := substr(unid10, b3*9-8, 9);
end if;
else
l3 := substr(dezenas, b2*9-8, 9);
end if;
end if;
if b3 != 0 then
if b2 != 1 then
l5 := substr(unidades, b3*6-5, 6);
end if;
end if;
if b1 != 0 or b2 != 0 or b3 != 0 then
if (b1 = 0 and b2 = 0) and b3 = 1 then
l5 := 'Hum';
l6 := ' Bilhão';
else
l6 := ' Bilhões';
end if;
if valor > 999999999 then
virgula_bi := ' e ';
if (b4+b5+b6+b7+b8+b9+b10+b11+b12) = 0 then
virgula_bi := ' de' ;
end if;
end if;
l1 := ltrim(l1);
l3 := ltrim(l3);
l5 := ltrim(l5);
if b2 > 1 and b3 > 0 then
l4 := ' e ';
end if;
if b1 != 0 and (b2 !=0 or b3 != 0) then
l2 := ' e ';
end if;
end if;
-- ROTINA DOS MILHOES --
if b4 != 0 then
if b4 = 1 then
if b5 = 0 and b6 = 0 then
l7 := 'Cem';
else
l7 := substr(centenas, b4*12-11, 12);
end if;
else
l7 := substr(centenas, b4*12-11, 12);
end if;
end if;
if b5 != 0 then
if b5 = 1 then
if b6 = 0 then
l11 := 'Dez';
else
l9 := substr(unid10, b6*9-8, 9);
end if;
else
l9 := substr(dezenas, b5*9-8, 9);
end if;
end if;
if b6 != 0 then
if b5 != 1 then
l11 := substr(unidades, b6*6-5, 6);
end if;
end if;
if b4 != 0 or b5 != 0 or b6 != 0 then
if (b4 = 0 and b5 = 0) and b6 = 1 then
l11 := ' Hum';
l12 := ' Milhão';
else
l12 := ' Milhões';
end if;
if valor > 999999 then
virgula_mi := ' e ';
if (b7+b8+b9+b10+b11+b12) = 0 then
virgula_mi := ' de';
end if;
end if;
l7 := ltrim(l7);
l9 := ltrim(l9);
l11 := ltrim(l11);
if b5 > 1 and b6 > 0 then
l10 := ' e ';
end if;
if b4 != 0 and (b5 !=0 or b6 != 0) then
l8 := ' e ';
end if;
end if;
-- ROTINA DOS MILHARES --
if b7 != 0 then
if b7 = 1 then
if b8 = 0 and b9 = 0 then
l17 := 'Cem';
else
l13 := substr(centenas, b7*12-11, 12);
end if;
else
l13 := substr(centenas, b7*12-11, 12);
end if;
end if;
if b8 != 0 then
if b8 = 1 then
if b9 = 0 then
l17 := 'Dez';
else
l15 := substr(unid10, b9*9-8, 9);
end if;
else
l15 := substr(dezenas, b8*9-8, 9);
end if;
end if;
if b9 != 0 then
if b8 != 1 then
l17 := substr(unidades, b9*6-5, 6);
end if;
end if;
if b7 != 0 or b8 != 0 or b9 != 0 then
if (b7 = 0 and b8 = 0) and b9 = 1 then
l17 := 'Hum';
l18 := ' Mil';
else
l18 := ' Mil';
end if;
if valor > 999 and (b10+b11+b12) !=0 then
virgula_mil := ' e ';
end if;
l13 := ltrim(l13);
l15 := ltrim(l15);
l17 := ltrim(l17);
if b8 > 1 and b9 > 0 then
l16 := ' e ';
end if;
if b7 != 0 and (b8 !=0 or b9 != 0) then
l14 := ' e ';
end if;
end if;
-- ROTINA DOS REAIS --
if b10 != 0 then
if b10 = 1 then
if b11 = 0 and b12 = 0 then
l19 := 'Cem';
else
l19 := substr(centenas, b10*12-11, 12);
end if;
else
l19 := substr(centenas, b10*12-11, 12);
end if;
end if;
if b11 != 0 then
if b11 = 1 then
if b12 = 0 then
l23 := 'Dez';
else
l21 := substr(unid10, b12*9-8, 9);
end if;
else
l21 := substr(dezenas, b11*9-8, 9);
end if;
end if;
if b12 != 0 then
if b11 != 1 then
l23 := substr(unidades, b12*6-5, 6);
end if;
end if;
if b10 != 0 or b11 != 0 or b12 != 0 then
if valor > 0 and valor < 2 then
l23 := 'Hum';
end if;
l19 := ltrim(l19);
l21 := ltrim(l21);
l23 := ltrim(l23);
if b11 > 1 and b12 > 0 then
l22 := ' e ';
end if;
if b10 != 0 and (b11 !=0 or b12 != 0) then
l20 := ' e ';
end if;
end if;
if valor > 0 and valor < 2 then
if b12!=0 then
l24 := ' Real';
end if;
else
if valor > 1 then
l24 := ' Reais';
end if;
end if;
-- TRATA CENTAVOS --
if b13 != 0 OR b14 != 0 then
if valor > 0 then
if (b12 != 0) or (b1+b2+b3+b4+b5+b6+b7+b8+b9+b10+b11+b12)!=0 then
L25 := ' e ';
end if;
end if;
if b13 != 0 then
if b13 = 1 then
if b14 = 0 then
l28 := 'Dez';
else
l26 := substr(unid10, b14*9-8, 9);
end if;
else
l26 := substr(dezenas, b13*9-8, 9);
end if;
end if;
if b14 != 0 then
if b13 != 1 then
l28 := substr(unidades, b14*6-5, 6);
end if;
end if;
if b13 != 0 or b14 != 0 then
if valor = 1 then
l28 := 'Hum';
end if;
l26 := ltrim(l26);
l28 := ltrim(l28);
if b13 > 1 and b14 > 0 then
l27 := ' e ';
end if;
end if;
if (b1+b2+b3+b4+b5+b6+b7+b8+b9+b10+b11+b12) > 0
then
if b13 = 0 and b14 = 1 then
l29 := ' Centavo';
else
l29 := ' Centavos';
end if;
else
if b13 = 0 and b14 = 1 then
l29 := ' Centavo de Real';
else
l29 := ' Centavos de Real';
end if;
end if;
end if;
-- CONCATENAR O LITERAL --
if l29 = ' Centavo de Real' or l29 = ' Centavos de Real' then
virgula_mil := '';
end if;
extenso := l1||l2||l3||l4||l5||l6||virgula_bi
||L7||L8||L9||L10||L11||l12||virgula_mi
||l13||l14||l15||l16||l17||l18||virgula_mil
||L19||L20||L21||L22||L23||l24||virgula_cr
||L25||L26||L27||L28||L29;
extenso := ltrim(extenso);
extenso := replace(extenso,' ',' ');
else
extenso := 'Zero';
end if;
return extenso;
end;
/
Depois da criação da função de banco de dados acima, mostrarei alguns exemplos de seu uso. Vale a pena salientar que a mesma funciona até o valor 999.999.999.999,99 como demonstrado abaixo.
SQL> select extenso(999999999999.99) from dual;
EXTENSO(999999999999.99)
------------------------------------------------------------------------------
Novecentos e Noventa e Nove Bilhões, Novecentos e Noventa e Nove Milhões,
Novecentos e Noventa e Nove Mil, Novecentos e Noventa e Nove Reais e Noventa e
Nove Centavos
SQL> select extenso(0.02) from dual;
EXTENSO(0.02)
------------------------------------
Dois Centavos de Real
SQL> select extenso(1) from dual;
EXTENSO(1)
------------------------------------
Hum Real
SQL> select extenso(1.56) from dual;
EXTENSO(1.56)
------------------------------------
Hum Real e Cinquenta e Seis Centavos
SQL> select extenso(1001.63) from dual;
EXTENSO(1001.63)
---------------------------------------------
Hum Mil e Um Reais e Sessenta e Tres Centavos
SQL> select extenso(52987.12) from dual;
EXTENSO(52987.12)
-------------------------------------------------------------------------
Cinquenta e Dois Mil e Novecentos e Oitenta e Sete Reais e Doze Centavos
SQL> select extenso(1000000) from dual;
EXTENSO(1000000)
-------------------
Hum Milhão de Reais
SQL> select extenso(1000000000) from dual;
EXTENSO(1000000000)
-------------------
Hum Bilhão de Reais
SQL> select extenso(1004060900) from dual;
EXTENSO(1004060900)
--------------------------------------------------------------
Hum Bilhão e Quatro Milhões e Sessenta Mil e Novecentos Reais
SQL> select extenso(160987) from dual;
EXTENSO(160987)
--------------------------------------------------------
Cento e Sessenta Mil e Novecentos e Oitenta e Sete Reais
Função PL/SQL para Cálculo de Fórmulas Matemáticas
Certa vez, fui encarregado de criar uma função de banco de dados para um sistema na qual a mesma teria que retornar um valor resultado do cálculo matemático de outros valores ou fórmulas. Como a função ficou complexa e de uso apenas para o sistema em questão por causa de suas tabelas e campos existentes, achei melhor simplificar o seu código para mostrar aqui o seu uso.
Esta função de banco de dados FUNC_CALC_FORMULA, faz uso de uma outra função auxiliar chamada FUNC_VALIDA_FORMULA utilizada para verificar se uma fórmula matemática é válida.
É importante salientar que, nesta função de banco de dados, eu faço uso de várias funções PL/SQL, como REPLACE, INSTR, UPPER, "EXECUTE IMMEDIATE", também faço o uso de Tabelas PL/SQL que são modeladas de forma parecida às tabelas do banco de dados e, que também, são semelhantes aos arrays (vetores) em PL/SQL do Oracle. Para exemplificar o uso desta função, seguirei os procedimentos abaixo:
Criação da Tabela que armazenará as fórmulas
SQL> CREATE TABLE TFORMULA(
2 COD_FORMULA VARCHAR2(4),
3 DESC_FORMULA VARCHAR2(100),
4 SEQUENCIA NUMBER);
Tabela criada.
SQL> ALTER TABLE TFORMULA ADD CONSTRAINT PK_FORMULA PRIMARY KEY (COD_FORMULA);
Tabela alterada.
SQL> CREATE UNIQUE INDEX I_SEQUENCIA ON TFORMULA (SEQUENCIA);
índice criado.
Carga da tabela com as fórmulas
SQL> INSERT INTO TFORMULA VALUES ('V001','10 * 1.1',1);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V002','20 + V001',2);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V003','(V002 + V001)/2',3);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V004','(V002 + V001)+ V003 * (V002 * 0.2)',4);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V005','V001 + 1',5);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V006','(((V004 * 1.10) + V005)/2) * 2',6);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V007','V006 * 0.1',7);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V008','(10 * V001) + V005 + V007',8);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V009','((V001 * 1.1) * (V008 * V001)) / 5',9);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V010','(V004 - V001) * 0.1',10);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V011','V009 + V010',11);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V012','V011 - 1',12);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V013','0.1 * 100',13);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V014','V002 + V013',14);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V015','(V014 - V001) * 0.32',15);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V016','(V009 + V015 - V002) + 10',16);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V017','(V003 + (V006/2)) * V013',17);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V018','(V017 + V008) / V003',18);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V019','V015 * 100',19);
1 linha criada.
SQL> INSERT INTO TFORMULA VALUES ('V020','V019 + V017 + V001 + V004',20);
1 linha criada.
SQL> COMMIT;
Validação completa.
No procedimento acima eu criei uma tabela que armazenará as fórmulas, bem como a seqüência necessária para realização do cálculo:
- COD_FORMULA: armazena o código da fórmula que poderá ser utilizado em outras fórmulas e que, necessariamente, deverá começar com a letra V. O tamanho do código da fórmula é definido pela variável N_TAMANHO da função
- FUNC_CALC_FORMULA que no meu caso é 4 (V000 até V999).
- DESC_FORMULA: armazena a fórmula matemática.
- SEQUENCIA: armazena o número de seqüência que a função deverá ler ordenada de forma ascendente para calcular o valor das fórmulas.
Podemos ver abaixo que os registros das fórmulas matemáticas foram inseridas na tabela TFORMULA.
SQL> select * from tformula order by sequencia;
COD_ DESC_FORMULA SEQUENCIA
---- ---------------------------------------- ----------
V001 10 * 1.1 1
V002 20 + V001 2
V003 (V002 + V001)/2 3
V004 (V002 + V001)+ V003 * (V002 * 0.2) 4
V005 V001 + 1 5
V006 (((V004 * 1.10) + V005)/2) * 2 6
V007 V006 * 0.1 7
V008 (10 * V001) + V005 + V007 8
V009 ((V001 * 1.1) * (V008 * V001)) / 5 9
V010 (V004 - V001) * 0.1 10
V011 V009 + V010 11
V012 V011 - 1 12
V013 0.1 * 100 13
V014 V002 + V013 14
V015 (V014 - V001) * 0.32 15
V016 (V009 + V015 - V002) + 10 16
V017 (V003 + (V006/2)) * V013 17
V018 (V017 + V008) / V003 18
V019 V015 * 100 19
V020 V019 + V017 + V001 + V004 20
20 linhas selecionadas.
Função FUNC_CALC_FORMULA
CREATE OR REPLACE FUNCTION FUNC_CALC_FORMULA (PCOD_FORMULA VARCHAR)
RETURN NUMBER AS
N_RETORNO NUMBER (17,2);
N_SEQUENCIA TFORMULA.SEQUENCIA%TYPE;
N_VALOR NUMBER;
N_FORMULA_VALIDA NUMBER;
N_TAMANHO NUMBER := 4;
S_FORMULA_PRINCIPAL VARCHAR2(4000);
S_FORMULA_SEQUENCIA VARCHAR2(4000);
S_AUX VARCHAR2(4000);
SQL_STMT VARCHAR2(4000);
E_PARAMETRO_NULO EXCEPTION;
E_FORMULA_INVALIDA EXCEPTION;
E_FORMULA_RECURSIVA EXCEPTION;
BEGIN
DECLARE
TYPE REG_CALC_FORMULA IS RECORD
(COD_FORMULA VARCHAR2(10),
VALOR NUMBER);
TYPE TP_ARRAY_CALC IS TABLE OF REG_CALC_FORMULA INDEX BY BINARY_INTEGER;
TAB_CALC TP_ARRAY_CALC;
CURSOR FORMULA IS
SELECT UPPER(COD_FORMULA) AS COD_FORMULA,
UPPER(RTRIM(LTRIM(DESC_FORMULA))) AS DESC_FORMULA,
SEQUENCIA
FROM TFORMULA
WHERE SEQUENCIA <= N_SEQUENCIA
ORDER BY SEQUENCIA;
BEGIN
IF RTRIM(LTRIM(PCOD_FORMULA)) IS NULL THEN
RAISE E_PARAMETRO_NULO;
END IF;
SELECT SEQUENCIA,UPPER(RTRIM(LTRIM(DESC_FORMULA))) AS DESC_FORMULA
INTO N_SEQUENCIA,S_FORMULA_PRINCIPAL
FROM TFORMULA
WHERE UPPER(COD_FORMULA) = UPPER(PCOD_FORMULA);
FOR REG_FORMULA IN FORMULA LOOP
FOR I IN 1..TAB_CALC.COUNT LOOP
S_FORMULA_PRINCIPAL :=
REPLACE(S_FORMULA_PRINCIPAL,TAB_CALC(I).COD_FORMULA,TO_CHAR(TAB_CALC(I).VALOR));
END LOOP;
IF INSTR(S_FORMULA_PRINCIPAL,'V') = 0 THEN
SQL_STMT := UPPER(REPLACE('SELECT '||S_FORMULA_PRINCIPAL||' FROM DUAL',',','.'));
N_FORMULA_VALIDA := FUNC_VALIDA_FORMULA(S_FORMULA_PRINCIPAL);
IF N_FORMULA_VALIDA = 0 THEN
RAISE E_FORMULA_INVALIDA;
END IF;
EXECUTE IMMEDIATE REPLACE(SQL_STMT,',','.') INTO N_VALOR;
N_RETORNO := N_VALOR;
EXIT;
END IF;
IF INSTR(REG_FORMULA.DESC_FORMULA,'V') = 0 THEN
SQL_STMT := UPPER(REPLACE('SELECT '||REG_FORMULA.DESC_FORMULA||' FROM DUAL',',','.'));
N_FORMULA_VALIDA := FUNC_VALIDA_FORMULA(REG_FORMULA.DESC_FORMULA);
IF N_FORMULA_VALIDA = 0 THEN
RAISE E_FORMULA_INVALIDA;
END IF;
EXECUTE IMMEDIATE REPLACE(SQL_STMT,',','.') INTO N_VALOR;
TAB_CALC(REG_FORMULA.SEQUENCIA).COD_FORMULA := REG_FORMULA.COD_FORMULA;
TAB_CALC(REG_FORMULA.SEQUENCIA).VALOR := N_VALOR;
ELSE
S_FORMULA_SEQUENCIA := REG_FORMULA.DESC_FORMULA;
WHILE INSTR(S_FORMULA_SEQUENCIA,'V',1,1) > 0 LOOP
S_AUX := SUBSTR(S_FORMULA_SEQUENCIA,INSTR(S_FORMULA_SEQUENCIA,'V',1),N_TAMANHO);
FOR I IN 1..TAB_CALC.COUNT LOOP
IF TAB_CALC(I).COD_FORMULA = S_AUX THEN
N_VALOR := TAB_CALC(I).VALOR;
EXIT;
ELSE
N_VALOR := NULL;
END IF;
END LOOP;
IF N_VALOR IS NOT NULL THEN
S_FORMULA_SEQUENCIA := REPLACE(S_FORMULA_SEQUENCIA,S_AUX,TO_CHAR(N_VALOR));
ELSE
RAISE E_FORMULA_RECURSIVA;
END IF;
END LOOP;
SQL_STMT := UPPER(REPLACE('SELECT '||S_FORMULA_SEQUENCIA||' FROM DUAL',',','.'));
N_FORMULA_VALIDA := FUNC_VALIDA_FORMULA(S_FORMULA_SEQUENCIA);
IF N_FORMULA_VALIDA = 0 THEN
RAISE E_FORMULA_INVALIDA;
END IF;
EXECUTE IMMEDIATE REPLACE(SQL_STMT,',','.') INTO N_VALOR;
TAB_CALC(REG_FORMULA.SEQUENCIA).COD_FORMULA := REG_FORMULA.COD_FORMULA;
TAB_CALC(REG_FORMULA.SEQUENCIA).VALOR := N_VALOR;
END IF;
N_RETORNO := N_VALOR;
END LOOP;
RETURN N_RETORNO;
END FUNC_CALC_FORMULA;
EXCEPTION
WHEN E_PARAMETRO_NULO THEN
RAISE_APPLICATION_ERROR (-20001,'Erro ao gerar o cálculo: Parâmetro nulo.');
WHEN E_FORMULA_INVALIDA THEN
RAISE_APPLICATION_ERROR (-20002,'Erro ao gerar o cálculo: Fórmula inválida.');
WHEN E_FORMULA_RECURSIVA THEN
RAISE_APPLICATION_ERROR (-20003,'Erro ao gerar o cálculo: Fórmula Recursiva.');
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20004,'Erro ao gerar o cálculo: '||SQLERRM);
END;
/
Função FUNC_VALIDA_FORMULA: (Usado dentro da função principal)
CREATE OR REPLACE FUNCTION FUNC_VALIDA_FORMULA (PFORMULA VARCHAR)
RETURN NUMBER AS
N_VALOR NUMBER;
N_TAMANHO NUMBER := 4;
SQL_STMT VARCHAR2(4000);
E_PARAMETRO EXCEPTION;
BEGIN
IF RTRIM(LTRIM(PFORMULA)) IS NULL THEN
RAISE E_PARAMETRO;
END IF;
N_VALOR := NULL;
SQL_STMT := UPPER(REPLACE('SELECT '||PFORMULA||' FROM DUAL',',','.'));
WHILE INSTR(SQL_STMT,'V',1,1) > 0 LOOP
SQL_STMT := REPLACE(SQL_STMT,SUBSTR(SQL_STMT,INSTR(SQL_STMT,'V',1,1),N_TAMANHO),'1');
END LOOP;
EXECUTE IMMEDIATE SQL_STMT INTO N_VALOR;
IF N_VALOR IS NOT NULL THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
EXCEPTION
WHEN E_PARAMETRO THEN
RETURN 1;
WHEN OTHERS THEN
RETURN 0;
END;
/
Para finalizar, segue abaixo alguns exemplos de como utilizar as funções de bancos de dados criadas neste artigo.
Exemplo 1
SQL> select cod_formula,desc_formula,func_calc_formula(cod_formula) from tformula;
COD_ DESC_FORMULA FUNC_CALC_FORMULA(COD_FORMULA)
---- ---------------------------------------- ------------------------------
V001 10 * 1.1 11
V002 20 + V001 31
V003 (V002 + V001)/2 21
V004 (V002 + V001)+ V003 * (V002 * 0.2) 172,2
V005 V001 + 1 12
V006 (((V004 * 1.10) + V005)/2) * 2 201,42
V007 V006 * 0.1 20,14
V008 (10 * V001) + V005 + V007 142,14
V009 ((V001 * 1.1) * (V008 * V001)) / 5 3783,82
V010 (V004 - V001) * 0.1 16,12
V011 V009 + V010 3799,94
V012 V011 - 1 3798,94
V013 0.1 * 100 10
V014 V002 + V013 41
V015 (V014 - V001) * 0.32 9,6
V016 (V009 + V015 - V002) + 10 3772,42
V017 (V003 + (V006/2)) * V013 1217,1
V018 (V017 + V008) / V003 64,73
V019 V015 * 100 960
V020 V019 + V017 + V001 + V004 2360,3
20 linhas selecionadas.
Exemplo 2
SQL> select func_calc_formula(cod_formula) valor from tformula where cod_formula = 'V020';
VALOR
------------
2360,30
SQL> select func_calc_formula(cod_formula) valor from tformula where cod_formula = 'V012';
VALOR
------------
3798,94
Inclusive podemos fazer uso da função "extenso" em conjunto com a função de cálculo de fórmulas como demonstrado a seguir:
SQL> select func_calc_formula(cod_formula) valor,
2 extenso(func_calc_formula(cod_formula)) extenso
3 from tformula;
VALOR EXTENSO
-------- -------------------------------------------------------------------------
11 Onze Reais
31 Trinta e Um Reais
21 Vinte e Um Reais
172,20 Cento e Setenta e Dois Reais e Vinte Centavos
12 Doze Reais
201,42 Duzentos e Um Reais e Quarenta e Dois Centavos
20,14 Vinte Reais e Quatorze Centavos
142,14 Cento e Quarenta e Dois Reais e Quatorze Centavos
3783,82 Tres Mil e Setecentos e Oitenta e Tres Reais e Oitenta e Dois Centavos
16,12 Dezesseis Reais e Doze Centavos
3799,94 Tres Mil e Setecentos e Noventa e Nove Reais e Noventa e Quatro Centavos
3798,94 Tres Mil e Setecentos e Noventa e Oito Reais e Noventa e Quatro Centavos
10 Dez Reais
41 Quarenta e Um Reais
9,60 Nove Reais e Sessenta Centavos
3772,42 Tres Mil e Setecentos e Setenta e Dois Reais e Quarenta e Dois Centavos
1217,10 Hum Mil e Duzentos e Dezessete Reais e Dez Centavos
64,73 Sessenta e Quatro Reais e Setenta e Tres Centavos
960 Novecentos e Sessenta Reais
2360,30 Dois Mil e Trezentos e Sessenta Reais e Trinta Centavos
20 linhas selecionadas.
3 comentários:
Funciona perfeitamente parabéns.
Eu to precisando do Número por extenso monetário, e sinceramente não entendi direito.
Não tenho tanta experiencia e me pareceu um tanto confuso, teria como me ajudar um pouco mais?
Obrigado
Olá,
A lógica PL/SQL por dentro da função pode parecer um pouco confusa, mas não há a necessidade de entendê-la. Portanto, basta apenas criar a função EXTENSO() no schema de banco de dados desejado utilizando o código PL/SQL postado no início do artigo e usá-la como demonstrado nos exemplos.
Até mais ...
Postar um comentário