Você está na página 1de 82

Exemplos de procedures úteis

[Nota] O código abaixo foi enviado por Luciano C. dos Santos, e fornece uma alternativa para
aqueles que não querem ou não gostam de usar UDFs em seus bancos de dados. A função de cada
procedure está descrita como comentário, no código da mesma.

Estas são as SPs que utilizo como auxiliares no desenvolvimento dos meus sistemas (no lugar de
UDFs). Vale observar que as escrevi bem no início do meu trabalho com FB, portanto as técnicas
de programação ainda podem ser um tanto rudimentares, mas funcionam. Quero alertar que
antes que as utilizem, façam testes, pois embora para mim estejam corretas, podem não ter o
comportamento esperado por outras pessoas.

Caso você encontre falhas ou melhore as funções, envie uma cópia para o meu email (abaixo).

Em tempo, as funções estão em ordem alfabética e como pode haver dependências entre elas,
atente para a ordem de criação das mesmas no banco de dados.

Luciano C dos Santos


Email: luciano em praticsistemas.com.br

*********************************************************
CREATE PROCEDURE FU_ABS(
WVAR DOUBLE PRECISION)
RETURNS (
R_ABS DOUBLE PRECISION)
AS
begin
/*
devolve o valor Absoluto de um número.
-123,47 ou 123,47 devolve sempre 123,47
*/
if (:wvar is not null) then begin
if (:wvar < 0.0000) then
r_abs = :wvar * -1;
else
r_abs = :wvar;
end
suspend;
end
===================================
CREATE PROCEDURE FU_ALLTRIM(
WVAR VARCHAR(8192))
RETURNS (
R_ALLTRIM VARCHAR(8192))
AS
DECLARE VARIABLE T SMALLINT;
begin
/*
Devolve um string sem espaços
*/
select r_Len from Fu_Len(:wvar) into :t;
r_alltrim = '';
while ((:wvar is not null) and (:t > 0)) do begin
if (substring(:wvar from 1 for 1) <> ' ') then
r_alltrim = :r_alltrim || substring(:wvar from 1 for 1);
wvar = substring(:wvar from 2 for 8191);
t = :t - 1;
end
suspend;
end
====================================
CREATE PROCEDURE FU_BEFORE_AFTER(
WPES VARCHAR(8192),
WVAR VARCHAR(8192),
WTIP CHAR(1))
RETURNS (
WRET VARCHAR(8192))
AS
declare variable wint smallint;
declare variable wlen smallint;
begin
/*
Devolve os caracteres "Anteriores" ou "Posteriores" de
um string tomando como base "WPES"
*/
wtip = upper(:wtip);
select result from Fu_Pos(:wpes, :wvar) into :wint;
if (:wtip = 'B') then -- Before
begin
if (:wint = 0) then
wret = wpes;
else
select r_Copy from Fu_Copy(:wvar, 1, (:wint - 1)) into :wret;
end
else begin -- After
if (:wint = 0) then
wret = '';
else begin
select r_Len from Fu_Len(:wpes) into :wlen;
select r_Copy from Fu_Copy(:wvar, (:wint + :wlen), 8191) into
:wret;
end
end
suspend;
end
================================================
CREATE PROCEDURE FU_CENTRO(
WSTR VARCHAR(8192),
WTAM SMALLINT)
RETURNS (
R_CENTRO VARCHAR(8192))
AS
DECLARE VARIABLE I SMALLINT;
DECLARE VARIABLE T SMALLINT;
DECLARE VARIABLE S VARCHAR(8192);
begin
/*
Devolve um string Centralizado Com o tamanho "WRAM"
*/
select r_Len from Fu_Len(:wstr) into :t;
if (:t > :wtam) then
select r_Copy from Fu_Copy(:wstr, 1, :wtam) into :r_centro;
else if (:t = :wtam) then
r_centro = :wstr;
else begin
select r_div from Fu_div((:wtam - :t), 2) into :i;
select r_replicate from Fu_replicate(:i, ' ') into :s;
wstr = :s || :wstr;
select r_replicate from Fu_replicate(((:wtam - :t) - :i), ' ') into
:s;
r_centro = :wstr || :s;
end
suspend;
end
==============================================
CREATE PROCEDURE FU_CLASS(
WSTR VARCHAR(8192),
WSUB VARCHAR(8192),
WDEL CHAR(1),
WORD CHAR(1))
RETURNS (
R_RET VARCHAR(8192))
AS
declare variable wpos smallint;
declare variable tra1 varchar(8192);
declare variable wfez smallint = 1;
begin
/*
Insere "WSUB" em "WSTR" na ordem ascending ou
descending (conforme "WORD"). "WSTR" deve estar delimitada por
"WDEL"
*/
select result from Fu_pos(:wdel, :wstr) into :wpos;
select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
if (:word = 'A') then --
Ordem Ascending...
begin
if (:wsub < :tra1) then -
- Se já for a primeira
r_ret = :wsub || :wdel || :wstr; --
Concatenar
else begin -
- Senão...
select r_last_pos from Fu_last_pos(:wdel, :wstr) into :wpos;
-- Última Posição do delimitador
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :tra1;
-- Última String
if (:wsub >= :tra1) then --
Se for a última
r_ret = :wstr || :wdel || :wsub; --
Concatenar
else begin --
Senão
select result from Fu_pos(:wdel, :wstr) into :wpos;
-- Posição do delimitador
select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
-- Primeira String
r_ret = :tra1 || :wdel; --
... e concatenar
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
-- STR resultante
while (:wfez = 1) do begin --
Enquanto não achar o lugar
select result from Fu_pos(:wdel, :wstr) into :wpos; -
- Posição do delimitador ns STR resultante
if (:wpos = 0) then -- Se
não tem mais...
tra1 = :wstr; --
Inicializo :TRA1
else --
Senão...
select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1; --
Defino
if (:wsub <= :tra1) then --
Comparo
begin
r_ret = :r_ret || :wsub || :wdel; --
Concateno se é o lugar
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;--
STR resultante
r_ret = :r_ret || :wstr; --
Concateno o restante
wfez = 0; --
Para sair do LOOP
end
else begin --
Senão...
r_ret = :r_ret || :wdel || :tra1; --
concateno
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr; --
STR resultante
end
end
end
end
end
else begin -- Orden Descending...
if (:tra1 < :wsub) then
r_ret = :wsub || :wdel || :wstr;
else begin
select r_last_pos from Fu_last_pos(:wdel, :wstr) into :wpos;
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :tra1;
if (:tra1 >= :wsub) then
r_ret = :wstr || :wdel || :wsub;
else begin
select result from Fu_pos(:wdel, :wstr) into :wpos;
select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
r_ret = :tra1 || :wdel;
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
while (:wfez = 1) do begin
select result from Fu_pos(:wdel, :wstr) into :wpos;
if (:wpos = 0) then
tra1 = :wstr;
else
select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
if (:tra1 <= :wsub) then
begin
r_ret = :r_ret || :wsub || :wdel;
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
r_ret = :r_ret || :wstr;
wfez = 0;
end
else begin
r_ret = :r_ret || :wdel || :tra1;
select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
end
end
end
end
end
suspend;
end
================================================
CREATE PROCEDURE FU_COPY(
WVAR VARCHAR(8192),
WINI INTEGER,
WTAM INTEGER)
RETURNS (
R_COPY VARCHAR(8192))
AS
DECLARE VARIABLE I INTEGER;
DECLARE VARIABLE J INTEGER;
DECLARE VARIABLE K INTEGER;
begin
/*
Copia de "WINI" "WTAM" bytes de "WVAR"
Este recurso não é mais necessário no FB 2
Pois já aceita o substring com variáveis
*/
select r_Len from Fu_Len(:wvar) into :i;
j = 1;
k = 1;
r_copy = '';
while ((:wvar is not null) and (:i > 0) and (j <= :wtam)) do begin
if (:k >= :wini) then begin
r_copy = :r_copy || substring(:wvar from 1 for 1);
j = j + 1;
end
wvar = substring(:wvar from 2 for 8191);
k = :k + 1;
i = :i - 1;
end
suspend;
end
========================================
CREATE PROCEDURE FU_CPA_PERI(
PER1 VARCHAR(8),
PER2 VARCHAR(8))
RETURNS (
R_CPA_PERI CHAR(1))
AS
begin
/*
Compara dois períodos (MM/AAAA) e devolve
"<", ">" ou "=" conforme o caso
*/
if ((:per1 is not null) and (:per2 is not null)) then begin
if ((substring(:per1 from 4 for 4) || substring(:per1 from 1 for
2)) =
(substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2)))
then
r_cpa_peri = '=';
else if ((substring(:per1 from 4 for 4) || substring(:per1 from 1
for 2)) >
(substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2)))
then
r_cpa_peri = '>';
else if ((substring(:per1 from 4 for 4) || substring(:per1 from 1
for 2)) <
(substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2)))
then
r_cpa_peri = '<';
end
suspend;
end
===========================================
CREATE PROCEDURE FU_CRIP(
WSTR VARCHAR(1024),
ACAO SMALLINT)
RETURNS (
R_STR VARCHAR(1024))
AS
DECLARE VARIABLE WS1 VARCHAR(255);
DECLARE VARIABLE WS2 VARCHAR(255);
DECLARE VARIABLE WLT CHAR(1);
DECLARE VARIABLE WIN SMALLINT;
DECLARE VARIABLE WLE SMALLINT;
DECLARE VARIABLE WPO SMALLINT;
begin
/*
Devolve um string criptografado se "ACAO" = 0
senão descriptografa. Função bem CASEIRA
*/
ws1 = ' [AaB1bC2(c+Ç3çD4dE5eF6fG7g)H8hI9iJ0jKk-
LlMmNn]OoPpQqRrSsTtUuVvXxYyWwZz"!@#$%¨&*_´`{^~}|\<,>.:;?/' ||
'éóúàèìòùêûâîôÁÉÍÓÚÀÈÌÒÙÃÕ¥¡¢£¤¦§¨©ª®°±²³µ•¸¹"¼¾¿ÅÆÏÐÑÖ×ÝÞö÷øýþ';
ws2 = 'éóúàèìòùêûâîôÁÉÍÓÚÀÈÌÒÙÃÕ¥¡¢£¤¦§¨©ª®°±²³µ•¸¹"¼¾¿ÅÆÏÐÑÖ×ÝÞö÷øýþ'
||
'
AB0CÇ9DE8FG7HI6JK5LM4NO3PQ2RS1TUVXYWZabcçdefghijklmnopqrstuvxywz"!@#$%
¨&*()_+´`{[^~}]|\<,>.:;?/-';
r_str = '';
select r_Len from Fu_Len(:wstr) into :wle;
win = 1;
if (:acao = 0) then -- Criptografa a string
begin
while (:win <= :wle) do begin
select r_Copy from Fu_Copy(:wstr, :win, 1) into :wlt;
select result from Fu_Pos(:wlt, :ws1) into :wpo;
if (:wpo > 0) then
select r_Copy from Fu_Copy(:ws2, :wpo, 1) into :wlt;
r_str = :r_str || :wlt;
win = :win + 1;
end
end
else begin -- desfaz a criptografia
while (:win <= :wle) do begin
select r_Copy from Fu_Copy(:wstr, :win, 1) into :wlt;
select result from Fu_Pos(:wlt, :ws2) into :wpo;
if (:wpo > 0) then
select r_Copy from Fu_Copy(:ws1, :wpo, 1) into :wlt;
r_str = :r_str || :wlt;
win = :win + 1;
end
end
suspend;
end
=========================================
CREATE PROCEDURE FU_CUBE(
WNUM DOUBLE PRECISION)
RETURNS (
RAIZ DOUBLE PRECISION)
AS
declare variable parc double precision;
declare variable wraz smallint = 3;
begin
/*
Devolve a Raiz Cúbica de um número.
Há uma tolerância em caso de inexato.
*/
select sqr from Fu_sqrt(:wnum) into :parc;
while (:wraz > 2) do begin
select sqr from Fu_sqrt(:parc) into :raiz;
wraz = :wraz - 1;
end
wraz = 3;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 1;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 1;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.50000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.50000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.10000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.250000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.050000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.050000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.001000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.0010000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.0001000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.00010000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.00001000;
parc = :raiz * raiz * :raiz;
end
if (:parc > :wnum) then begin
raiz = :raiz - 0.000010000;
parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
raiz = :raiz + 0.000001000;
parc = :raiz * raiz * :raiz;
end
end
end
end
end
end
end
end
parc = cast(:raiz as integer);
if ((:parc * :parc * :parc) = :wnum) then
raiz = :parc;
suspend;
end
======================================
CREATE PROCEDURE FU_DATATELA(
DAT1 DATE,
DAT2 VARCHAR(24),
TIPO CHAR(1))
RETURNS (
DATA_TELA VARCHAR(19))
AS
begin
/*
Devolve uma data ou um TaimeStamp como:
DD/MM/YY ou DD/MM/YYYY ou
DD/MM/YY HH:MM:SS ou DD/MM/YYYY HH:MM:SS
como um string (Bom para relatórios)
*/
tipo = upper(:tipo);
if(:dat1 is not null) then
begin
if (:tipo = 'E') then
data_tela = substring(cast(:dat1 as varchar(10)) from 9 for 2) ||
'/' ||
substring(cast(:dat1 as varchar(10)) from 6 for 2) || '/' ||
substring(cast(:dat1 as varchar(10)) from 1 for 4);
else
data_tela = substring(cast(:dat1 as varchar(10)) from 9 for 2) ||
'/' ||
substring(cast(:dat1 as varchar(10)) from 6 for 2) || '/' ||
substring(cast(:dat1 as varchar(10)) from 2 for 2);
end
else begin
if (tipo = 'E') then
data_tela = substring(:dat2 from 9 for 2) || '/' ||
substring(:dat2 from 6 for 2) || '/' ||
substring(:dat2 from 1 for 4) || ' ' ||
substring(:dat2 from 12 for 8);
else
data_tela = substring(:dat2 from 9 for 2) || '/' ||
substring(:dat2 from 6 for 2) || '/' ||
substring(:dat2 from 2 for 2) || ' ' ||
substring(:dat2 from 12 for 8);
end
suspend;
end
================================================
CREATE PROCEDURE FU_DATE_TO_INTEGER(
WDAT CHAR(10))
RETURNS (
R_DTI INTEGER)
AS
declare variable wano smallint;
declare variable wmes smallint;
declare variable wdia smallint;
declare variable trab integer;
declare variable wmat integer;
begin
/*
Devolve um inteiro conforme a data informada
"WDAT" deve vir assim: aaaa-mm-dd
*/
wano = cast(substring(:wdat from 1 for 4) as smallint);
wmes = cast(substring(:wdat from 6 for 2) as smallint);
wdia = cast(substring(:wdat from 9 for 2) as smallint);
if (:wmes = 2) then wmat = 31;
else if (:wmes = 3) then wmat = 59;
else if (:wmes = 4) then wmat = 90;
else if (:wmes = 5) then wmat = 120;
else if (:wmes = 6) then wmat = 151;
else if (:wmes = 7) then wmat = 181;
else if (:wmes = 8) then wmat = 212;
else if (:wmes = 9) then wmat = 243;
else if (:wmes = 10) then wmat = 273;
else if (:wmes = 11) then wmat = 304;
else if (:wmes = 12) then wmat = 334;
else wmat = 0;
select r_abs from fu_abs(((:wano - 1901) * 366)) into :trab;
r_dti = :trab + :wmat + :wdia;
suspend;
end
============================================
CREATE PROCEDURE FU_DECIMAL_HORA(
FNUM DECIMAL(10,4))
RETURNS (
HORA VARCHAR(10),
WHOR INTEGER,
WMIN INTEGER)
AS
declare variable wint integer;
declare variable wtam integer;
declare variable trab varchar(14);
declare variable tra1 varchar(14);
begin
/*
Se "FNUM" = 10,50 então devolve 10,30... etc
Se "FNUM" = 15,20 então devolve 15,12
*/
select r_formatar from Fu_formatar(:fnum, '######0,0000') into
:trab;
select r_sright from Fu_s_right(:trab, 1) into
:tra1;
select r_ltrim from Fu_ltrim(:trab) into
:trab;
select r_len from Fu_len(:trab) into
:wtam;
while (:tra1 = '0') do begin
select r_sleft from Fu_s_left(:trab, :wtam - 1) into :trab;
select r_sright from Fu_s_right(:trab, 1) into :tra1;
wtam = :wtam - 1;
end
tra1 = :trab;
select result from Fu_pos(',', :trab) into :wint;
select r_copy from Fu_Copy(:trab, (:wint + 1), (:wtam - :wint)) into
:trab;
wmin = cast(:trab as integer);
wmin = :wmin * 6;
select r_div from Fu_div(:wmin, 10) into :wmin;
select r_copy from Fu_Copy(:tra1, 1, (:wint - 1)) into :trab;
whor = cast(:trab as integer);
while (:wmin > 60) do begin
wmin = :wmin - 60;
whor = :whor + 1;
end

hora = cast(:whor as varchar(6));


select r_len from Fu_len(:trab) into :wtam;
if (:wtam = 1) then
hora = '0' || :hora;
select r_intzero from Fu_intzero(:wmin, 2) into :trab;
hora = :hora || ':' || :trab;
suspend;
end
======================================
CREATE PROCEDURE FU_DECODE_DATE(
WDAT DATE)
RETURNS (
RDIA SMALLINT,
RMES SMALLINT,
RANO SMALLINT)
AS
begin
/*
Igual ao Delphi
*/
rdia = extract(day from :wdat);
rmes = extract(month from :wdat);
rano = extract(year from :wdat);
suspend;
end
=======================================
CREATE PROCEDURE FU_DECODE_DATE_TIME(
WDAT TIMESTAMP)
RETURNS (
RDIA SMALLINT,
RMES SMALLINT,
RANO SMALLINT,
RHOR SMALLINT,
RMIN SMALLINT,
RSEG DECIMAL(6,4),
WEEK SMALLINT,
YDIA SMALLINT)
AS
declare variable trab varchar(24);
begin
/*
Igual ao Delphi
*/
trab = cast(:wdat as varchar(24));
rdia = extract(day from :wdat);
rmes = extract(month from :wdat);
rano = extract(year from :wdat);
if (substring(:trab from 12 for 13) = '00:00:00.0000') then
begin
rhor = 0;
rmin = 0;
rseg = 0.0000;
end
else begin
rhor = extract(hour from :wdat);
rmin = extract(minute from :wdat);
rseg = extract(second from :wdat);
end
week = extract(weekday from :wdat);
ydia = extract(yearday from :wdat);
suspend;
end
===================================
CREATE PROCEDURE FU_DIV(
WRAD INTEGER,
WDIV INTEGER)
RETURNS (
R_DIV INTEGER)
AS
begin
/*
Igual ao Delphi
*/
R_DIV = :WRAD / :WDIV;
suspend;
end
=====================================
CREATE PROCEDURE FU_DSTR(
WSTR VARCHAR(8192),
WTAM SMALLINT)
RETURNS (
R_DSTR VARCHAR(8192))
AS
DECLARE VARIABLE T SMALLINT;
declare variable s varchar(8192);
begin
/*
Devolve um string com espaços à direita até
o tamanho "WTAM"
*/
select r_Len from Fu_Len(:wstr) into :t;
if (:wstr is null) then
wstr = '';
if (:t > :wtam) then
select r_Copy from Fu_Copy(:wstr, 1, :wtam) into :r_dstr;
else begin
select r_spaces from Fu_spaces(:wtam - :t) into :s;
r_dstr = :wstr || :s;
end
suspend;
end
=========================================
CREATE PROCEDURE FU_DVMODULO10(
WSTR VARCHAR(50))
RETURNS (
WDIG INTEGER)
AS
declare variable wsom integer;
declare variable wreg integer;
declare variable wmul integer;
declare variable wini integer;
declare variable winj integer;
declare variable winh integer;
declare variable trab varchar(6);
begin
/*
Dígito Verificador Módulo 10
*/
wsom = 0;
wreg = 0;
wmul = 2;
select r_Len from Fu_Len(:wstr) into :wini;
winh = :wini;
winj = 1;
while (:winj <= :wini) do begin
select r_Copy from Fu_Copy(:wstr, :winh, 1) into :trab;
wreg = cast(:trab as integer) * :wmul;
wsom = :wsom + :wreg;
if (:wmul = 2) then
wmul = 1;
else
wmul = :wmul + 1;
winj = :winj + 1;
winh = :winh - 1;
end
select r_mod from Fu_mod(:wsom, 10) into :wdig;
suspend;
end
==========================================
CREATE PROCEDURE FU_DVMODULO11(
WSTR VARCHAR(50))
RETURNS (
WDIG INTEGER)
AS
declare variable wsom integer;
declare variable wreg integer;
declare variable wmul integer;
declare variable wini integer;
declare variable winj integer;
declare variable winh integer;
declare variable wxi1 integer;
declare variable wxi2 integer;
declare variable waux char(2);
declare variable wax1 char(1);
declare variable wax2 char(1);
declare variable wtra varchar(10);
begin
/*
Dígito Verificador Módulo 11
*/
wsom = 0;
wreg = 0;
wmul = 2;
select r_Len from Fu_Len(:wstr) into :wini;
winh = :wini;
winj = 1;
while (:winj <= :wini) do begin
select r_Copy from Fu_Copy(:wstr, :winh, 1) into :wtra;
wreg = cast(:wtra as integer) * :wmul;
while (:wreg > 9) do begin
waux = cast(:wreg as char(2));
wax1 = substring(:waux from 1 for 1);
wax2 = substring(:waux from 2 for 1);
wxi1 = cast(:wax1 as integer);
wxi2 = cast(:wax2 as integer);
wreg = :wxi1 + :wxi2;
end
wsom = :wsom + :wreg;
if (:wmul = 9) then
wmul = 2;
else
wmul = :wmul + 1;
winj = :winj + 1;
winh = :winh - 1;
end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
if ((:wdig = 10) or (:wdig = 1) or (:wdig = 0)) then
wdig = 0;
suspend;
end
=======================================
CREATE PROCEDURE FU_ESTR(
WSTR VARCHAR(8192),
WTAM SMALLINT)
RETURNS (
R_ESTR VARCHAR(8192))
AS
DECLARE VARIABLE T SMALLINT;
begin
/*
Devolve um string com espaços à direita conforme "WTAM"
*/
select r_Len from Fu_Len(:wstr) into :t;
r_estr = :wstr;
if (:t > :wtam) then
select r_Sright from Fu_S_Right(:wstr, :wtam) into :r_estr;
else begin
while (:t < :wtam) do begin
r_estr = ' ' || :r_estr;
t = :t + 1;
end
end
suspend;
end
==============================================
CREATE PROCEDURE FU_EXTENSO(
VALO DECIMAL(18,2),
LIN1 INTEGER,
LIN2 INTEGER)
RETURNS (
R_EXT1 VARCHAR(126),
R_EXT2 VARCHAR(126),
R_EXT3 VARCHAR(256))
AS
declare variable nao1 varchar(16);
declare variable nao2 varchar(50);
declare variable nao3 varchar(16);
declare variable nao4 varchar(25);
declare variable wvlr varchar(16);
declare variable trab varchar(256);
declare variable tra1 varchar(16);
declare variable rext varchar(256);
declare variable wint integer;
declare variable wtri integer;
declare variable var1 integer;
declare variable var2 integer;
declare variable var3 integer;
begin
/*
Devolve duas linhas com o número "VALO" por extenso
a primeira linha tem "LIN1" de tamanho e
a segunda linha tem "LIN2" de tamanho.
Também é feita uma separação silábica considerando as
regras de sintaxe da l´ngua portuguesa.
Utiliza-se em conjunto as SPs FU_EXT_TESTA1 e FU_EXT_TESTA2 abaixo
*/
if (Lin1 = 0) then
Lin1 = 1;
if (Lin2 = 0) then
Lin2 = 1;
if (:Lin1 > 128) then Lin1 = 125;
if (:Lin2 > 128) then Lin2 = 125;
nao1 = 'bctdrqvhêõãm?';
nao2 = ' o; n; s; u;ci;ei;nh;ce;qu;he;nz;oz;rz;ai;ss;uz';
nao3 = 'rea;are;doi;ato';
nao4 = 'trez;uinh;nhen;uato;ssei';
r_ext1 = '';
wvlr = '';
wint = 1;
if (:valo < 0.01) then valo = :valo * -1;
select r_Formatar from Fu_Formatar(:valo, '##########0,00') into
:rext;
while (:wint < 15) do begin
select r_Copy from Fu_Copy(:rext, :wint, 1) into :trab;
select result From Fu_Pos(:trab, '0123456789,') into :wtri;
if (:wtri > 0) then wvlr = :wvlr || :trab;
wint = :wint + 1;
end
rext = '';
select result From Fu_Pos(',', :wvlr) into :wtri;
if (:wtri = 0) then wvlr = :wvlr || ',00';
select r_Len from Fu_Len(:wvlr) into :wtri;
while (:wtri < 14) do begin
wvlr = '0' || :wvlr;
wtri = :wtri + 1;
end
if (substring(:wvlr from 13 for 1) = ',') then
wvlr = substring(:wvlr from 2 for 11) || ',' || substring(:wvlr
from 14 for 1) || '0';
if (cast(substring(:wvlr from 1 for 2) as integer) > 0) then begin
trab = substring(:wvlr from 1 for 2);
var1 = 0;
var2 = cast(substring(:trab from 1 for 1) as integer);
var3 = cast(substring(:trab from 2 for 1) as integer);
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
if (:trab = '01') then
rext = :rext || ' bilhão';
else
rext = :rext || ' bilhões';
if (substring(:wvlr from 3 for 9) = '000000000') then
rext = :rext || ' de reais';
else begin
if ((substring(:wvlr from 3 for 3) = '000') and
(substring(:wvlr from 6 for 1) = '0') or
(substring(:wvlr from 6 for 6) = '000000') or
(substring(:wvlr from 7 for 8) = '00000,00')) then
rext = :rext || ' e ';
else
rext = :rext || ' , ';
end
end
if (substring(:wvlr from 3 for 3) > '000') then begin
var1 = cast(substring(:wvlr from 3 for 1) as integer);
var2 = cast(substring(:wvlr from 4 for 1) as integer);
var3 = cast(substring(:wvlr from 5 for 1) as integer);
if (:var1 > 0) then
begin
select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into
:rext;
if ((:var2 + :var3) > 0) then
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
end
else
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
if ((:var1 + :var2 = 0) and (:var3 = 1)) then
rext = :rext || ' milhão';
else
rext = :rext || ' milhões';
if (substring(:wvlr from 6 for 6) = '000000') then
rext = :rext || ' de reais';
else if ((substring(:wvlr from 6 for 3) = '000') and
(substring(:wvlr from 13 for 2) = '00')) then
rext = :rext || ' e ';
else
rext = :rext || ', ';
end
if (substring(:wvlr from 6 for 3) > '000') then begin
var1 = cast(substring(:wvlr from 6 for 1) as integer);
var2 = cast(substring(:wvlr from 7 for 1) as integer);
var3 = cast(substring(:wvlr from 8 for 1) as integer);
if (:var1 > 0) then
begin
select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into
:rext;
if ((:var2 + :var3) > 0) then
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
end
else
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
rext = :rext || ' mil';
if (substring(:wvlr from 9 for 3) = '000') then
rext = :rext || ' reais';
else if ((substring(:wvlr from 9 for 3) > '000') and
(substring(:wvlr from 13 for 2) > '00')) then
rext = :rext || ', ';
else
rext = :rext || ' e ';
end
if (substring(:wvlr from 9 for 3) > '000') then begin
var1 = cast(substring(:wvlr from 9 for 1) as integer);
var2 = cast(substring(:wvlr from 10 for 1) as integer);
var3 = cast(substring(:wvlr from 11 for 1) as integer);
if (:var1 > 0) then
begin
select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into
:rext;
if ((:var2 + :var3) > 0) then
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
end
else
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
if (substring(:wvlr from 1 for 11) > '00000000001') then
rext = :rext || ' reais';
else
rext = :rext || ' real';
end
if (substring(:wvlr from 13 for 2) > '00') then begin
select r_Len from Fu_Len(:rext) into :wint;
if (:wint > 2) then
rext = :rext || ' e ';
var1 = 0;
var2 = cast(substring(:wvlr from 13 for 1) as integer);
var3 = cast(substring(:wvlr from 14 for 1) as integer);
select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
rext = :rext || ' centavo';
if (substring(:wvlr from 13 for 2) > '01') then
rext = :rext || 's';
end
select r_Len from Fu_Len(:rext) into :wtri;
select r_replicate from Fu_Replicate(:lin2, '*') into r_ext2;
select r_replicate from Fu_Replicate(:lin2, '*') into r_ext3;
if (:wtri = :lin1) then
r_ext1 = :rext;
else if (:wtri < :lin1) then
begin
select r_replicate from Fu_Replicate((:lin1 - :wtri), '*') into
r_ext1;
r_ext1 = :rext || :r_ext1;
end
else begin -- Se não for igual nem menor então é maior
-- Preparo a primeira variável
var1 = 0;
select r_Copy from Fu_Copy(:rext, 1, :lin1) into :r_ext1; -- a
variável
select r_Copy from Fu_Copy(:rext, (:lin1 + 1), (:lin2 + :lin2))
into :rext; -- sobrou
while (:var1 = 0) do begin
var1 = 1; -- Suponho que farei este
passo apenas esta vez
-- Verifico a separação silábica com uma casa
select r_Len from Fu_Len(:r_ext1) into :var2;
select r_Copy from Fu_Copy(:r_ext1, :var2, 1) into :tra1;
select result From Fu_Pos(:tra1, :nao1) into :var3;
if (:var3 > 0) then begin -- Letra final não permitida
select r_Copy from Fu_Copy(:r_ext1, :var2, 1) into :tra1;
rext = :tra1 || :rext; -- Coloco na sobra
select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 1)) into :r_ext1; -
- Tiro daqui
var1 = 0; -- Fazer o passo (while) novamente
end
-- Verifico a separação silábica com duas casas
select r_Len from Fu_Len(:r_ext1) into :var2;
select r_Copy from Fu_Copy(:r_ext1, (:var2 -1), 2) into :tra1;
select result From Fu_Pos(:tra1, :nao2) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext1, (:var2 - 1), 2) into :tra1;
rext = :tra1 || :rext; -- Coloco na sobra
select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 2)) into :r_ext1;
-- Tiro daqui
var1 = 0; -- Fazer o passo (while) novamente
end
-- Verifico a separação silábica com três casas
select r_Len from Fu_Len(:r_ext1) into :var2;
select r_Copy from Fu_Copy(:r_ext1, (:var2 - 2), 3) into :tra1;
select result From Fu_Pos(:tra1, :nao3) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext1, (:var2 - 2), 3) into :tra1;
rext = :tra1 || :rext; -- Coloco na sobra
select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 3)) into :r_ext1;
-- Tiro daqui
var1 = 0; -- Fazer o passo (while)
novamente
end
-- Verifico a separação silábica com quatro casas
select r_Len from Fu_Len(:r_ext1) into :var2;
select r_Copy from Fu_Copy(:r_ext1, (:var2 - 3), 4) into :tra1;
select result From Fu_Pos(:tra1, :nao4) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext1, (:var2 - 3), 4) into :tra1;
rext = :tra1 || :rext; -- Coloco na sobra
select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 4)) into :r_ext1;
-- Tiro daqui
var1 = 0; -- Fazer o passo (while)
novamente
end
end
-- Ajustando o tamanho da primeira
select r_Len from Fu_Len(:r_ext1) into :var2;
if (:var2 < :lin1) then begin
select r_Dstr From Fu_DStr(:r_ext1, :lin1) into :r_ext1;
select r_Copy from Fu_Copy(:r_ext1, :lin1, 1) into :tra1;
if (:tra1 <> ' ') then begin
select r_Copy from Fu_Copy(:r_ext1, 1, (:lin1 - 1)) into :r_ext1;
r_ext1 = :r_ext1 || '-';
end
end
-- Preparando a segunda variável (sempre existirá)
select r_Len from Fu_Len(:rext) into :var2; -- Apuro
o comprimento da sobra
if (:var2 <= :lin2) then -- Se não houver a terceira string
igualo e completo
begin
r_ext2 = :rext;
select r_Replicate from Fu_Replicate((:lin2 - :var2), '*') into
:rext;
r_ext2 = :r_ext2 || :rext;
end
else begin -- Tem
terceira variável
-- Preparo a segunda
var1 = 0;
select r_Copy from Fu_Copy(:rext, 1, :lin2) into :r_ext2; --
Copio novo conteúdo
select r_Copy from Fu_Copy(:rext, (:lin2 + 1), :lin2) into :rext;
-- sobrou
select r_RTrim from Fu_RTrim(:r_ext2) into :r_ext2; --
Retiro espaços
while (:var1 = 0) do begin
var1 = 1;
select r_Len from Fu_Len(:r_ext2) into :var2;
select r_Copy from Fu_Copy(:r_ext2, :var2, 1) into :tra1;
select result From Fu_Pos(:tra1, :nao1) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext2, :var2, 1) into :tra1;
rext = :tra1 || :rext;
select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 1)) into :r_ext2;
var1 = 0;
end
select r_Len from Fu_Len(:r_ext2) into :var2;
select r_Copy from Fu_Copy(:r_ext2, (:var2 -1), 2) into :tra1;
select result From Fu_Pos(:tra1, :nao2) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext2, (:var2 - 1), 2) into :tra1;
rext = :tra1 || :rext;
select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 2)) into :r_ext2;
var1 = 0;
end
select r_Len from Fu_Len(:r_ext2) into :var2;
select r_Copy from Fu_Copy(:r_ext2, (:var2 - 2), 3) into :tra1;
select result From Fu_Pos(:tra1, :nao3) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext2, (:var2 - 2), 3) into :tra1;
rext = :tra1 || :rext;
select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 3)) into :r_ext2;
var1 = 0;
end
select r_Len from Fu_Len(:r_ext2) into :var2;
select r_Copy from Fu_Copy(:r_ext2, (:var2 - 3), 4) into :tra1;
select result From Fu_Pos(:tra1, :nao4) into :var3;
if (:var3 > 0) then begin
select r_Copy from Fu_Copy(:r_ext2, (:var2 - 3), 4) into :tra1;
rext = :tra1 || :rext;
select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 4)) into :r_ext2;
var1 = 0;
end
-- Ajustando o tamanho da segunda
select r_Len from Fu_Len(:r_ext2) into :var2;
if (:var2 < :lin2) then begin
select r_Dstr From Fu_DStr(:r_ext2, :lin2) into :r_ext2;
select r_Copy from Fu_Copy(:r_ext2, :lin1, 1) into :tra1;
if (:tra1 <> ' ') then begin
select r_Copy from Fu_Copy(:r_ext2, 1, (:lin2 - 1)) into :r_ext2;
r_ext2 = :r_ext2 || '-';
end
end
-- Preparando a terceira variável (sempre existirá)
select r_Len from Fu_Len(:rext) into :var2;
select r_Replicate from Fu_Replicate((:lin2 - :var2), '*') into
:r_ext3;
r_ext3 = :rext || :r_ext3;
end
end
end
if (substring(:r_ext2 from 1 for 4) = 's***') then begin
r_ext1 = :r_ext1 || 's';
r_ext2 = '*' || substring(:r_ext2 from 2 for 125);
end
r_ext1 = upper(substring(:r_ext1 from 1 for 1)) || substring(:r_ext1
from 2 for 125);
suspend;
end
==================================================
CREATE PROCEDURE FU_EXT_TESTA1(
WEXT VARCHAR(255),
VAR1 INTEGER,
VAR2 INTEGER,
VAR3 INTEGER)
RETURNS (
R_EXT_1 VARCHAR(255))
AS
begin
/*
Auxiliar de FU_EXTENSO
*/
if (:var1 = 1) then
begin
if (:var2 + :var3 = 0) then
wext = :wext || 'cem';
else
wext = :wext || 'cento';
end
else if (:var1 = 2) then
wext = :wext || 'duzentos';
else if (:var1 = 3) then
wext = :wext || 'trezentos';
else if (:var1 = 4) then
wext = :wext || 'quatrocentos';
else if (:var1 = 5) then
wext = :wext || 'quinhentos';
else if (:var1 = 6) then
wext = :wext || 'seiscentos';
else if (:var1 = 7) then
wext = :wext || 'setecentos';
else if (:var1 = 8) then
wext = :wext || 'oitocentos';
else if (:var1 = 9) then
wext = :wext || 'novecentos';
if (:var2 + :var3 > 0) then
wext = :wext || ' e ';
r_ext_1 = :wext;
suspend;
end
===========================================
CREATE PROCEDURE FU_EXT_TESTA2(
WEXT VARCHAR(255),
VAR2 INTEGER,
VAR3 INTEGER)
RETURNS (
R_EXT_2 VARCHAR(255))
AS
begin
/*
Auxiliar de FU_EXTENSO
*/
if (:var2 = 1) then
begin
if (:var3 = 0) then
wext = :wext || 'dez';
else if (:var3 = 1) then
wext = :wext || 'onze';
else if (:var3 = 2) then
wext = :wext || 'doze';
else if (:var3 = 3) then
wext = :wext || 'treze';
else if (:var3 = 4) then
wext = :wext || 'quatorze';
else if (:var3 = 5) then
wext = :wext || 'quinze';
else if (:var3 = 6) then
wext = :wext || 'dezesseis';
else if (:var3 = 7) then
wext = :wext || 'dezessete';
else if (:var3 = 8) then
wext = :wext || 'dezoito';
else if (:var3 = 9) then
wext = :wext || 'dezenove';
end
else if (:var2 = 2) then
wext = :wext || 'vinte';
else if (:var2 = 3) then
wext = :wext || 'trinta';
else if (:var2 = 4) then
wext = :wext || 'quarenta';
else if (:var2 = 5) then
wext = :wext || 'cinquenta';
else if (:var2 = 6) then
wext = :wext || 'sessenta';
else if (:var2 = 7) then
wext = :wext || 'setenta';
else if (:var2 = 8) then
wext = :wext || 'oitenta';
else if (:var2 = 9) then
wext = :wext || 'noventa';
if (:var2 <> 1) then begin
if (:var3 > 0) then begin
if (:var2 > 0) then
wext = :wext || ' e ';
if (:var3 = 1) then
wext = :wext || 'um';
else if (:var3 = 2) then
wext = :wext || 'dois';
else if (:var3 = 3) then
wext = :wext || 'três';
else if (:var3 = 4) then
wext = :wext || 'quatro';
else if (:var3 = 5) then
wext = :wext || 'cinco';
else if (:var3 = 6) then
wext = :wext || 'seis';
else if (:var3 = 7) then
wext = :wext || 'sete';
else if (:var3 = 8) then
wext = :wext || 'oito';
else if (:var3 = 9) then
wext = :wext || 'nove';
end
end
r_ext_2 = :wext;
suspend;
end
=====================================
CREATE PROCEDURE FU_EXTRACT_STR(
WSUB VARCHAR(8192),
WSTR VARCHAR(8192))
RETURNS (
WRET VARCHAR(8192))
AS
declare variable wlen smallint;
declare variable wint smallint;
declare variable wpos smallint;
declare variable wvar varchar(8192);
begin
/*
Retira de "WSTR" uma "WSUB" Encontrada
*/
select r_Len from Fu_Len(:wsub) into :wlen;
select r_Len from Fu_Len(:wstr) into :wint;
select result from Fu_Pos(:wsub, :wstr) into :wpos;
if (:wpos = 0) then
wret = :wstr;
else begin
select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :wret;
select r_Copy from Fu_Copy(:wstr, (:wpos + :wlen), 8191) into
:wvar;
wret = :wret || :wvar;
end
suspend;
end
==========================================
CREATE PROCEDURE FU_FERIADOS_DATAS(
WDAT DATE)
RETURNS (
WTIP CHAR(1))
AS
declare variable c integer;
declare variable d integer;
declare variable g integer;
declare variable h integer;
declare variable i integer;
declare variable j integer;
declare variable l integer;
declare variable m integer;
declare variable w integer;
declare variable de date;
declare variable ds date;
declare variable dp date;
declare variable cc date;
declare variable wano integer;
declare variable wfer varchar(40) =
'0101,0421,0501,0907,1012,1102,1115,1225';
declare variable trab varchar(5);
begin
/*
Localiza feriados nacionais e religiosos de um ano
*/
wtip = 'U';
if (:wdat is not null) then begin
w = extract(weekday from :wdat);
if (:w = 0) then
wtip = 'D';
else if (:w = 6) then
wtip = 'B';
trab = substring(cast(:wdat as varchar(10)) from 6 for 2) ||
substring(cast(:wdat as varchar(10)) from 9 for 2);
select result from Fu_pos(:trab, :wfer) into i;
if (:i > 0) then -- Feriado Indicado em WFER
wtip = 'F';
end
-- Ver se é Páscoa
select rdia, rmes, rano from Fu_decode_date(:wdat) into :d, :m,
:wano;
select r_mod from Fu_Mod(:wano, 19) into :g;
select r_div from Fu_Div(:wano, 100) into :c;
-- Cálculo de H (C - C div 4 - (8 * C + 13) div 25 + 19 * G + 15) mod
30;)
select r_div from Fu_Div(:c, 4) into :w;
h = c - w;
w = (8 * :c) + 13;
select r_div from Fu_Div(:w, 25) into :w;
h = :h - :w + (19 * :g) + 15;
select r_mod from Fu_Mod(:h, 30) into :h;
-- Cálculo de i (H - (H div 28) * (1 - (H div 28) * (29 div (H + 1)) *
((21 - G) div 11)) )
select r_div from Fu_Div(:h, 28) into :w; -- H DIV 28
select r_div from Fu_Div(29, (:h + 1)) into :m; -- 29 DIV (h + 1)
select r_div from Fu_Div((21 - :g), 11) into :l; -- ((21 - G) div
11)
i = (:h - :w) * 1 - (:w * :m * :l);
-- Cálculo de j ((ano + ano div 4 + I + 2 - C + C div 4) mod 7)
select r_div from Fu_Div(:wano, 4) into :w;
select r_div from Fu_Div(:c, 4) into :l;
select r_mod from Fu_Mod(:wano + :w + :i + 2 - :c + :l, 7) into :j;
l = :i - :j;
-- Cálculo de m (3 + (L + 40) div 44)
select r_div from Fu_Div((:l + 40), 44) into :w;
m = 3 + :w;
-- Cálculo de d (L + 28 - 31 * (m div 4))
select r_div from Fu_Div((:m + 44), 44) into :w;
d = (:l + 28) - 31 * :w;
-- Finalmente acha DE (Como o domingo de Páscoa)
if (:d < 10) then
de = cast(substring(cast(:wdat as varchar(10)) from 1 for 5) ||
'0' || cast(:m as char(1)) || '-0' || cast(:d as char(1)) as date);
else
de = cast(substring(cast(:wdat as varchar(10)) from 1 for 5) ||
'0' || cast(:m as char(1)) || '-' || cast(:d as char(2)) as date);
-- Páscoa
dp = :de;
w = extract(weekday from :de);
while (:w > 1) do begin
de = :de + 1;
w = extract(weekday from :de);
end
-- Sexta-Feira Santa
ds = :de - 2;
-- Corpus Christi
cc = :ds + 62;
-- Carnaval
de = :de - 47;
if (:wdat = :de) then -- È Carnaval
wtip = 'C';
else if (:wdat = :ds) then -- É Sexta-Feira Santa
wtip = 'S';
else if (:wdat = :dp) then -- É Páscoa
wtip = 'P';
else if (:wdat = :cc) then -- É Corpus Christi
wtip = 'T';
suspend;
end
============================================
CREATE PROCEDURE FU_FORMATAR(
WVLR DECIMAL(15,4),
WMOD VARCHAR(32))
RETURNS (
R_FORMATAR VARCHAR(32))
AS
declare variable vls varchar(44);
declare variable dcm SmallInt;
declare variable vir SmallInt;
declare variable win SmallInt;
declare variable tam SmallInt;
declare variable npo smallint;
declare variable trb varchar(2);
begin
/*
Recebe um decimal e um modelo de máscara e devolve
uma forma adequada p/ impressão.
Ex: 1234,56 e "###.##0,00" devolve " 1.234,56" ou ainda
-1234,56 e "###.##0,00" devolve " -1.234,56" ou ainda
-1234,56 e "A##.##0,00" devolve " 1.234,56" ou ainda (valor
absoluto) ou ainda
1234,56 e '***.**0,00" devolve "**1.234,56"
*/
if ((substring(:wmod from 1 for 1) = 'A') and (:wvlr < 0)) then
begin -- Se for valor absoluto
select r_abs from fu_abs(:wvlr) into :wvlr;
select result from Fu_pos('*', :wmod) into :npo;
if (:npo > 0) then
wmod = '*' || substring(:wmod from 2);
else begin
select result from Fu_pos('$', :wmod) into :npo;
if (:npo > 0) then
wmod = '$' || substring(:wmod from 2);
else
wmod = '#' || substring(:wmod from 2);
end
end
vls = cast(:wvlr as varchar(32)); -- Valor como
String
select r_len from Fu_len(:vls) into :tam; -- Tamanho
do Valor como String
select r_len from Fu_len(:wmod) into :win; -- Tamanho
da Máscara
select result from Fu_pos(',', :wmod) into :dcm;
dcm = :win - :dcm;
select wret from Fu_replace_all_str(:vls, '.', ',') into :vls;
select r_len from Fu_len(:vls) into :tam; -- Tamanho
do Valor como String
select result from Fu_pos(',', :vls) into :vir;
vir = :tam - :vir;
while (:vir > :dcm) do begin
tam = :tam - 1;
select r_copy from Fu_copy(:vls, 1, :tam) into vls;
vir = :vir - 1;
end
if (:dcm > 4) then begin
while (:vir < :dcm) do begin
vls = :vls || '0';
vir = :vir + 1;
end
end
select r_len from Fu_Len(:vls) into :tam; -- Tamanho do
Valor como String
r_formatar = '';
while ((:win > 0) or (:tam > 0)) do begin
if ((:win = 0) and (:tam > 0)) then
begin
select r_copy from Fu_copy(:vls, :tam, 1) into :trb;
r_formatar = :trb || :r_formatar;
tam = :tam - 1;
end
else begin
select r_sright from Fu_s_right(:wmod, 1) into :trb;
select r_copy from Fu_copy(:wmod, 1, (:win -1)) into :wmod;
if (:tam = 0) then
begin
if (:trb in ('#', 'A', '.')) then
r_formatar = ' ' || :r_formatar;
else
r_formatar = :trb || :r_formatar;
end
else begin
if (:trb = '.') then
r_formatar = '.' || r_formatar;
else begin
select r_copy from Fu_copy(:vls, :tam, 1) into :trb;
r_formatar = :trb || :r_formatar;
tam = :tam - 1;
select r_copy from Fu_copy(:vls, 1, :tam) into :vls;
end
end
win = :win - 1;
end
end
select result from fu_pos('-.', :r_formatar) into :dcm;
if (:dcm > 0) then
select wret from fu_replace_str(' -', :r_formatar, :dcm) into
:r_formatar;
else if (substring(:r_formatar from 1 for 1) = '.') then
select wret from fu_replace_str(' ', :r_formatar, 1) into
:r_formatar;
else begin
select result from fu_pos(' .', :r_formatar) into :dcm;
if (:dcm > 0) then
select wret from fu_replace_str(' ', :r_formatar, :dcm) into
:r_formatar;
end
suspend;
end
===============================================
CREATE PROCEDURE FU_HORA_DECIMAL(
FHOR VARCHAR(8))
RETURNS (
WDEC DECIMAL(10,2))
AS
declare variable whor integer;
declare variable wmin integer;
declare variable wint integer;
declare variable wtam integer;
declare variable trab varchar(10);
begin
/*
recebe uma hora tipo HH:MM e devolve em decimal
Ex: Recebe 3:23 e devolve 3,38
*/
select result from Fu_pos(':', :fhor) into :wint;
select r_len from Fu_len(:fhor) into :wtam;
if (:wint = 0) then
begin
wmin = 0;
select r_onlydigit from Fu_onlydigit(:fhor) into :trab;
wdec = cast(:trab as decimal(10, 2));
end
else begin
select r_copy from Fu_copy(:fhor, :wint + 1, :wtam - :wint) into
:trab;
wmin = cast(:trab as integer);
select r_copy from Fu_copy(:fhor, 1, :wint - 1) into :trab;
whor = cast(:trab as integer);
while (:wmin > 60) do begin
wmin = :wmin - 60;
whor = :whor + 1;
end
wdec = cast((:wmin / 60.00) as decimal(10, 2));
wdec = cast(:whor + :wdec as decimal(10, 2));
end
suspend;
end
=============================================
CREATE PROCEDURE FU_INC_DEC_MES(
WDAT DATE,
WQTD SMALLINT)
RETURNS (
R_INC_DEC_MES DATE)
AS
DECLARE VARIABLE WDIA SMALLINT;
DECLARE VARIABLE WMES SMALLINT;
DECLARE VARIABLE WANO SMALLINT;
DECLARE VARIABLE WINT SMALLINT;
DECLARE VARIABLE WTRM CHAR(2);
DECLARE VARIABLE WTRD CHAR(2);
begin
/*
Incrementa ou decrementa meses em uma data
Se "WQTD" > 0 incrementa senão decrementa
*/
wdia = extract(day from :wdat);
wmes = extract(month from :wdat);
wano = extract(year from :wdat);
wmes = :wmes + :wqtd;
if (:wqtd > 0) then
begin
while (:wmes > 12) do begin
wano = :wano + 1;
wmes = :wmes - 12;
end
end
else begin
while (:wmes < 1) do begin
wano = :wano - 1;
wmes = :wmes + 12;
end
end
if ((:wmes = 2) and (:wdia > 28)) then
begin
select r_mod from Fu_mod(:wano, 4) into :wint;
if ((:wint = 0) and (:wdia > 29)) then
wdia = 29;
else if ((:wint > 0) and (:wdia > 28)) then
wdia = 28;
end
else if (:wdia > 30) then begin
if ((:wmes = 4) or (:wmes = 6) or (:wmes = 9) or (:wmes = 11)) then
wdia = 30;
end
select r_IntZero from Fu_IntZero(:wdia, 2) into :wtrd;
select r_IntZero from Fu_IntZero(:wmes, 2) into :wtrm;
r_Inc_Dec_Mes = cast(cast(:wano as varchar(4)) || '-' ||
:wtrm || '-' || :wtrd as date);
suspend;
end
=============================================
CREATE PROCEDURE FU_INC_DEC_PERI(
WPER VARCHAR(7),
WQTD SMALLINT)
RETURNS (
R_INC_DEC_PERI VARCHAR(7))
AS
DECLARE VARIABLE WMES SMALLINT;
DECLARE VARIABLE WANO SMALLINT;
begin
/*
Incrementa ou decrementa meses em um mês e ano.
Se "WQTD" > 0 incrementa senão decrementa
*/
wmes = cast(substring(:wper from 1 for 2) as SmallInt) + :wqtd;
wano = cast(substring(:wper from 4 for 4) as SmallInt);
if (:wqtd < 0) then
begin
while (:wmes < 1) do begin
wmes = :wmes + 12;
wano = :wano - 1;
end
end
else begin
while (:wmes > 12) do begin
wmes = :wmes - 12;
wano = :wano + 1;
end
end
select r_IntZero from Fu_IntZero(:wmes, 2) into r_Inc_Dec_peri;
r_Inc_Dec_Peri = :r_inc_dec_peri || '/' || cast(:wano as
varchar(4));
suspend;
end
==============================================
CREATE PROCEDURE FU_INSERT_STR(
WSUB VARCHAR(2048),
WSTR VARCHAR(2048),
WPOS SMALLINT)
RETURNS (
WRET VARCHAR(4096))
AS
declare variable wlen smallint;
declare variable wvar varchar(255);
begin
/*
Insere um string em outro na posição "WPOS"
*/
select r_Len from Fu_Len(:wstr) into :wlen;
if (:wlen <= :wpos) then
wret = :wstr || :wsub;
else begin
select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :wret;
select r_Copy from Fu_Copy(:wstr, :wpos, 255) into :wvar;
wret = :wret || :wsub || :wvar;
end
suspend;
end
===========================================
CREATE PROCEDURE FU_INTBRANCOS(
WINT BIGINT,
WTAM INTEGER)
RETURNS (
R_INTBRANCOS VARCHAR(36))
AS
begin
/*
Recebe um inteiro e devolve um string com brancos à esquerda no
tamanho "WTAM"
*/
if (:wint is null) then
select r_replicate from Fu_replicate(:wtam, ' ') into r_IntBrancos;
else
select r_Sright from Fu_S_Right(' ' || cast(:wint
as varchar(18)), :wtam) into :r_intbrancos;
suspend;
end
========================================
CREATE PROCEDURE FU_INTZERO(
WINT BIGINT,
WTAM INTEGER)
RETURNS (
R_INTZERO VARCHAR(8192))
AS
begin
/*
Recebe um inteiro e devolve um string com zeros à esquerda no
tamanho "WTAM"
*/
if (:wint is null) then
select r_replicate from Fu_replicate(:wtam, ' ') into r_IntZero;
else begin
select r_abs from fu_abs(:wint) into :wint;
select r_Sright from Fu_S_Right('000000000000000000' || cast(:wint
as varchar(18)), :wtam) into :r_intzero;
end
suspend;
end
=====================================
CREATE PROCEDURE FU_LASTDAY(
WANO SMALLINT,
WMES SMALLINT)
RETURNS (
R_LASTDAY SMALLINT)
AS
declare variable i integer;
begin
/*
Recebe um ano e um mês e devolve o último dia do mês daquele ano
*/
if ((:wmes = 1) or (:wmes = 3) or (:wmes = 5) or (:wmes = 7) or
(:wmes = 8) or (:wmes = 10) or (:wmes = 12)) then
r_Lastday = 31;
else if (:wmes = 2) then
begin
select r_mod from Fu_Mod(:wano, 4) into :i;
if (:i = 0) then
r_Lastday = 29;
else
r_Lastday = 28;
end
else
r_Lastday = 30;
suspend;
end
=========================================
CREATE PROCEDURE FU_LAST_POS(
WSUB VARCHAR(8192),
WSTR VARCHAR(8192))
RETURNS (
R_LAST_POS SMALLINT)
AS
declare variable wtam smallint;
declare variable trab varchar(8192);
declare variable wint smallint = 1;
begin
/*
Devolve a última posição do "WSUB" dentro do "WSTR"
*/
r_last_pos = 0;
if ((:wsub is not null) and (:wstr is not null)) then begin
select r_len from Fu_len(:wsub) into :wtam;
while (:wstr <> '') do begin
select r_copy from Fu_copy(:wstr, 1, :wtam) into :trab;
if (:trab = :wsub) then
r_last_pos = :wint;
wint = :wint + 1;
wstr = substring(:wstr from 2);
end
end
suspend;
end
===========================================
CREATE PROCEDURE FU_LEN(
WSTR VARCHAR(8192))
RETURNS (
R_LEN SMALLINT)
AS
DECLARE VARIABLE L varchar(10);
begin
/*
Devolve o tamanho em bytes de um string
no FB 2 não é mais necessário
*/
if (:wstr = 'MithBuster') then
r_Len = 10;
else begin
wstr = :wstr || 'MithBuster';
r_Len = 0;
l = substring(:wstr from 1 for 10);
while (:l <> 'MithBuster') do begin
r_Len = :r_Len + 1;
wstr = substring(:wstr from 2);
l = substring(:wstr from 1 for 10);
end
end
suspend;
end
==============================================
CREATE PROCEDURE FU_LTRIM(
WVAR VARCHAR(8192))
RETURNS (
R_LTRIM VARCHAR(8192))
AS
DECLARE VARIABLE J INTEGER;
DECLARE VARIABLE K INTEGER;
begin
/*
Devolve um string sem espaços à esquerda
*/
j = 0;
select r_Len from Fu_Len(:wvar) into :k;
r_ltrim = '';
while ((:wvar is not null) and (:k > 0)) do begin
if (:j > 0) then
r_ltrim = r_ltrim || substring(:wvar from 1 for 1);
else if (substring(:wvar from 1 for 1) <> ' ') then begin
r_ltrim = r_ltrim || substring(:wvar from 1 for 1);
j = 1;
end
wvar = substring(:wvar from 2 for 8191);
k = :k - 1;
end
suspend;
end
==========================================
CREATE PROCEDURE FU_MES_EXT(
WMES SMALLINT,
WCEN CHAR(1),
WTIP CHAR(1))
RETURNS (
R_MES_EXT VARCHAR(9))
AS
begin
/*
Devolve o mês por extenso (WMES) conforme o modelo desejado (WTIP)
*/
if (:wtip = 'R') then
begin
if (:wmes = 1) then r_mes_ext = 'JAN';
else if (:wmes = 2) then r_mes_ext = 'FEV';
else if (:wmes = 3) then r_mes_ext = 'MAR';
else if (:wmes = 4) then r_mes_ext = 'ABR';
else if (:wmes = 5) then r_mes_ext = 'MAI';
else if (:wmes = 6) then r_mes_ext = 'JUN';
else if (:wmes = 7) then r_mes_ext = 'JUL';
else if (:wmes = 8) then r_mes_ext = 'AGO';
else if (:wmes = 9) then r_mes_ext = 'SET';
else if (:wmes = 10) then r_mes_ext = 'OUT';
else if (:wmes = 11) then r_mes_ext = 'NOV';
else if (:wmes = 12) then r_mes_ext = 'DEZ';
end
else if (:wcen = 'S') then
begin
if (:wmes = 1) then r_mes_ext = ' JANEIRO ';
else if (:wmes = 2) then r_mes_ext = 'FEVEREIRO';
else if (:wmes = 3) then r_mes_ext = ' MARÇO ';
else if (:wmes = 4) then r_mes_ext = ' ABRIL ';
else if (:wmes = 5) then r_mes_ext = ' MAIO ';
else if (:wmes = 6) then r_mes_ext = ' JUNHO ';
else if (:wmes = 7) then r_mes_ext = ' JULHO ';
else if (:wmes = 8) then r_mes_ext = ' AGOSTO ';
else if (:wmes = 9) then r_mes_ext = 'SETEMBRO ';
else if (:wmes = 10) then r_mes_ext = ' OUTUBRO ';
else if (:wmes = 11) then r_mes_ext = 'NOVEMBRO ';
else if (:wmes = 12) then r_mes_ext = 'DEZEMBRO ';
end
else begin
if (:wmes = 1) then r_mes_ext = 'JANEIRO';
else if (:wmes = 2) then r_mes_ext = 'FEVEREIRO';
else if (:wmes = 3) then r_mes_ext = 'MARÇO';
else if (:wmes = 4) then r_mes_ext = 'ABRIL';
else if (:wmes = 5) then r_mes_ext = 'MAIO';
else if (:wmes = 6) then r_mes_ext = 'JUNHO';
else if (:wmes = 7) then r_mes_ext = 'JULHO';
else if (:wmes = 8) then r_mes_ext = 'AGOSTO';
else if (:wmes = 9) then r_mes_ext = 'SETEMBRO';
else if (:wmes = 10) then r_mes_ext = 'OUTUBRO';
else if (:wmes = 11) then r_mes_ext = 'NOVEMBRO';
else if (:wmes = 12) then r_mes_ext = 'DEZEMBRO';
end
suspend;
end
=========================================
CREATE PROCEDURE FU_MINUTESBETWEEN(
WD1 TIMESTAMP,
WD2 TIMESTAMP)
RETURNS (
R_MINUTESBETWEEN INTEGER)
AS
begin
/*
Minutos entre dois TS
*/
r_MinutesBetween =
(cast(substring(cast(:wd2 as varchar(24)) from 15 for 2) as
integer) +
(cast(substring(cast(:wd2 as varchar(24)) from 12 for 2) as
integer) * 60)) -
(cast(substring(cast(:wd1 as varchar(24)) from 15 for 2) as
integer) +
(cast(substring(cast(:wd1 as varchar(24)) from 12 for 2) as
integer) * 60)) +
cast((:wd2 - :wd1) as integer) * 1440;
suspend;
end
=============================================
CREATE PROCEDURE FU_MOD(
WRAD INTEGER,
WDIV INTEGER)
RETURNS (
R_MOD INTEGER)
AS
begin
/*
Resto da divisão entre inteiros
*/
if(:wrad < :wdiv) then
r_mod = :wdiv;
else
R_MOD = :WRAD - ((:WRAD / :WDIV) * :WDIV);
suspend;
end
===========================================
CREATE PROCEDURE FU_ONLYCHAR(
WVAR VARCHAR(255))
RETURNS (
R_ONLYCHAR VARCHAR(255))
AS
DECLARE VARIABLE K INTEGER;
declare variable i integer;
begin
/*
A partir de um string devolve somente o que não for números
*/
select r_Len from Fu_Len(:wvar) into :k;
r_onlychar = '';
while (:k > 0) do begin
select result from Fu_Pos(substring(:wvar from 1 for 1),
'0123456789') into :i;
if (:i = 0) then
r_onlychar = r_onlychar || substring(:wvar from 1 for 1);
wvar = substring(:wvar from 2 for 255);
k = :k - 1;
end
suspend;
end
==========================================
CREATE PROCEDURE FU_ONLYDIGIT(
WVAR VARCHAR(255))
RETURNS (
R_ONLYDIGIT VARCHAR(255))
AS
DECLARE VARIABLE K INTEGER;
DECLARE VARIABLE I INTEGER;
begin
/*
A partir de um string devolve apenas o que for número
*/
select r_Len from Fu_Len(:wvar) into :k;
r_onlydigit = '';
while (:k > 0) do begin
select result from Fu_Pos(substring(:wvar from 1 for 1),
'0123456789') into :i;
if (:i > 0) then
r_onlydigit = r_onlydigit || substring(:wvar from 1 for 1);
wvar = substring(:wvar from 2 for 254);
k = :k - 1;
end
suspend;
end
=======================================
CREATE PROCEDURE FU_POS(
SUB VARCHAR(8192),
STR VARCHAR(8192))
RETURNS (
RESULT SMALLINT)
AS
DECLARE VARIABLE SUB2 VARCHAR(8192);
DECLARE VARIABLE TMP VARCHAR(8192);
BEGIN
/*
Devolve a primeira posição de "SUB" dentro de "STR"
*/
if ((Sub is null) or (Str is null)) then begin
result = 0;
exit;
end
Sub2 = Sub || '%';
Tmp = '';
result = 1;
while ((Str not like Sub2) and (Str not like Tmp)) do begin
Sub2 = '_' || Sub2;
Tmp = Tmp || '_';
result = :result + 1;
end
if (Str like Tmp) then
result = 0;
suspend;
end
==============================================
CREATE PROCEDURE FU_QUEBRA_LINHA(
WVAR VARCHAR(8192),
WTAM SMALLINT)
RETURNS (
WLIN1 VARCHAR(8192),
WLIN2 VARCHAR(8192))
AS
declare variable wini SmallInt;
declare variable wstr char(1);
begin
/*
WVAR = um string supostamente maior que uma linha de impressão
desejada
WTAM = O tamanho do espaço (linha) de impressão desejada
OBS: Quando se digitar em tela um varchar digamos de 900 bytes se
for pressionado um ENTER
Em qualquer tempo antes do final então devemos gravar "<BR>" <-- =
à quebra de linha no HTML
Então enviamos o Stringão e o tamanho e serão devolvidas linhas com
até WTAM em bytes respeitando
sempre uma quebra com espaços ou <BR>. Sem quebrar uma aplavra pelo
meio
Devolve WLIN1 com o string a ser impresso e WLIN2 com o resto até
que WLIN2 seja NULL
*/
if (:wvar is not null) then begin -
- A variável está definida
if ((:wtam is null) or (:wtam = 0)) then --
Tamamho não definido (só copia)
wlin1 = :wvar;
else begin --
Tamanho está definido
if (substring(:wvar from 1 for 4) = '<BR>') then
begin
wlin1 = '';
wlin2 = substring(:wvar from 5 for 8188);
end
else begin
select result from Fu_Pos('<BR>', :wvar) into :wini;
if (:wini > 0) then
begin
if (:wini > :wtam) then
begin
select r_copy from Fu_Copy (:wvar, 1, :wtam) into :wlin1;
select r_copy from Fu_Copy (:wvar, (:wtam + 1), (8192 - :wtam))
into :wlin2;
end
else begin
select r_copy from Fu_copy (:wvar, 1, (:wini - 1)) into :wlin1;
select r_copy from Fu_copy (:wvar, (:wini + 4), (8192 - (:wini +
4))) into :wlin2;
end
end
else begin
select r_copy from Fu_copy (:wvar, 1, :wtam) into :wlin1;
select r_copy from Fu_copy (:wvar, (:wtam + 1), (8192 - :wtam))
into :wlin2;
end
select r_rtrim from Fu_rtrim (:wlin1) into :wlin1;
select r_len from Fu_len (:wlin1) into :wini;
if (:wini = :wtam) then begin
select result from Fu_pos(' ', :wlin1) into :wini;
if (:wini > 0) then begin
select r_sright from Fu_s_right(:wlin1, 1) into :wstr;
select r_len from Fu_len (:wlin1) into :wtam;
while ((:wstr <> ' ') and (:wtam > 0)) do begin
select r_copy from Fu_Copy(:wlin1, 1, (:wtam - 1)) into :wlin1;
wlin2 = :wstr || :wlin2;
select r_sright from Fu_s_right(:wlin1, 1) into :wstr;
wtam = :wtam - 1;
end
end
end
end -- O tamanho é superior ao solicitado (quebra foi
necessária)
end -- O tamanho estava definido
end -- A variável estava definida
if (:wlin2 = '') then
wlin2 = null;
if (:wlin2 is not null) then
select r_ltrim from Fu_ltrim(:wlin2) into :wlin2;
else
wlin2 = null;
suspend;
end
====================================================
CREATE PROCEDURE FU_REPLACE_ALL_STR(
WSTR VARCHAR(2048),
OSTR VARCHAR(128),
NSTR VARCHAR(128))
RETURNS (
WRET VARCHAR(8192))
AS
declare variable wlen smallint;
declare variable part varchar(128);
begin
/*
Troca wm WSTR tudo que encontrar igual a OSTR(OLD) por NSTR (NEW)
*/
select r_len from Fu_len(:ostr) into :wlen;
wret = '';
while (:wstr <> '') do begin
select r_copy from Fu_copy(:wstr, 1, :wlen) into :part;
if (:part <> :ostr) then
begin
wret = :wret || substring(:wstr from 1 for 1);
wstr = substring(:wstr from 2);
end
else begin
wret = :wret || :nstr;
select r_copy from Fu_copy(:wstr, :wlen + 1, 2047) into :wstr;
end
end
suspend;
end
============================================
CREATE PROCEDURE FU_REPLACE_STR(
WSUB VARCHAR(2048),
WSTR VARCHAR(2048),
WPOS SMALLINT)
RETURNS (
WRET VARCHAR(4096))
AS
declare variable wlen smallint;
declare variable wint smallint;
begin
/*
Troca WSUB em WSTR na posição WPOS
*/
select r_Len from Fu_Len(:wstr) into :wint;
if (:wint <= :wpos) then
begin
select r_DStr from Fu_DStr(:wstr, :wpos -1) into :wret;
wret = :wret || :wsub;
end
else begin
select r_Len from Fu_Len(:wsub) into :wlen;
select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :wret;
wret = :wret || :wsub;
select r_Len from Fu_Len(:wret) into :wlen;
select r_Copy from Fu_Copy(:wstr, :wlen + 1, :wint - :wlen) into
:wstr;
wret = :wret || :wstr;
end
suspend;
end
=======================================
CREATE PROCEDURE FU_REPLICATE(
WQTD INTEGER,
WVAR VARCHAR(255))
RETURNS (
R_REPLICATE VARCHAR(8192))
AS
begin
/*
Replica WQTD caracteres ou strings em WVAR
*/
r_replicate = '';
while (:wqtd > 0) do begin
r_replicate = r_replicate || :wvar;
wqtd = :wqtd - 1;
end
suspend;
end
=========================================
CREATE PROCEDURE FU_RTRIM(
WVAR VARCHAR(8192))
RETURNS (
R_RTRIM VARCHAR(8192))
AS
DECLARE VARIABLE I INTEGER;
declare variable s varchar(1);
begin
/*
Retira os espaços à direita de um string
*/
select r_Len from Fu_Len(:wvar) into :i;
if ((:i < 2) or (:wvar = ' ')) then
r_rtrim = '';
else begin
while ((:i > 0) and (:wvar is not null)) do begin
select r_Sright from Fu_S_Right(:wvar, 1) into :s;
if (:s = ' ') then
begin
select r_copy from Fu_copy(:wvar, 1, (:i - 1)) into :wvar;
i = :i - 1;
end
else
break;
end
r_rtrim = :wvar;
end
suspend;
end
================================================
CREATE PROCEDURE FU_SEM_ACENTOS(
WSTR VARCHAR(1024))
RETURNS (
R_SEM_ACENTOS VARCHAR(1024))
AS
DECLARE VARIABLE CA VARCHAR(53);
DECLARE VARIABLE SA VARCHAR(53);
DECLARE VARIABLE WI SMALLINT;
DECLARE VARIABLE WT SMALLINT;
declare variable i integer;
DECLARE VARIABLE WS VARCHAR(2);
begin
/*
Substitui caracteres acentuados de um string pelo correspondente
sem acento.
Útil para enviarmos string para impressoras matriciais ou Arquivos
eletrônicos
*/
if (:wstr is null) then
wstr = '';
ca = '%°ºáàâãäéèêëíìîïóòôõöúùûüçÁÀÂÃÄÉÈÊËÍÌÎÏÓÒÔÕÖÚÙÛÜÇâÂñÑ';
sa = '%rºaaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUCaAhH';
select r_Len from Fu_Len(:wstr) into :wt;
wi = 1;
r_sem_acentos = '';
while (:wt > 0) do begin
select r_Copy from Fu_Copy(:wstr, :wi, 1) into :ws;
if (:ws <> ' ') then begin
select result from Fu_Pos(:ws, :ca) into :i;
if (:i > 0) then begin
if (:ws = 'ñ') then
ws = 'nh';
else if (:ws = 'Ñ') then
ws = 'NH';
else
select r_Copy from Fu_Copy(:sa, :i, 1) into :ws;
end
end
r_sem_acentos = :r_sem_acentos || :ws;
wt = :wt - 1;
wi = :wi + 1;
end
suspend;
end
==========================================
CREATE PROCEDURE FU_SORT_B(
WSTR VARCHAR(8192),
WDEL CHAR(1),
WORD CHAR(1))
RETURNS (
WRET VARCHAR(8192))
AS
declare variable tra1 varchar(8192);
declare variable wpos smallint;
begin
/*
Classifica um string delimitado por WDEL na ordem WORD (A,D)
*/
select result from Fu_pos(:wdel, :wstr) into :wpos;
-- Primeiro delimitador
select r_copy from Fu_copy(:wstr, 1, (:wpos -1)) into :tra1;
-- Primeira String
wret = :tra1; --
Primeiro retorno = String
select r_copy from Fu_copy(:wstr, (:wpos + 1), 8191) into :wstr;
-- STR resultante
while (:wstr <> '') do begin --
Enquanto houver uma String...
select result from Fu_pos(:wdel, :wstr) into :wpos;
-- Primeiro delimitador da STR resultante
if (:wpos = 0) then -- Se
não tem mais...
begin
tra1 = :wstr; --
Inicializo :TRA1
wstr = ''; --
Esvazio STR resultante
end
else --
Senão...
select r_copy from Fu_copy(:wstr, 1, (:wpos - 1)) into :tra1; -
- Primeira String
select r_ret from Fu_class(:wret, :tra1, :wdel, :word) into :wret; --
Rotina de Classificação
select r_copy from Fu_copy(:wstr, (:wpos + 1), 8191) into :wstr;
-- String resultante
end
suspend;
end
============================================
CREATE PROCEDURE FU_SPACES(
WQTD INTEGER)
RETURNS (
R_SPACES VARCHAR(8192))
AS
begin
/*
devolve WQTD espaços em um string
*/
r_spaces = '';
while (:wqtd > 0) do begin
r_spaces = r_spaces || ' ';
wqtd = :wqtd - 1;
end
suspend;
end
===========================================
CREATE PROCEDURE FU_SQRT(
NUM DOUBLE PRECISION)
RETURNS (
SQR DOUBLE PRECISION)
AS
declare variable inc integer = 1;
declare variable pas integer;
declare variable nua double precision;
begin
/*
Devolve a Raiz Quadrade de um número
Há uma tolerância ou margem de erro para raizes inaxatas
*/
pas = 0; -- Passos (= SQR)
nua = :num; -- Salvando caso
não seja inteiro
while (:num > 0) do begin
num = :num - :inc;
inc = :inc + 2;
pas = :pas + 1;
end
if (:num = 0) then
sqr = :pas; -- Quadrado
perfeito
else begin -- Há fração
sqr = :pas -1; -- Maior quadrado
que não ultrapasse
sqr = cast((:sqr + 0.0001) as double precision);
-- Otimizando de Quartas em Quartas partes (Divide o tempo de
processamento por 4)
if ((:sqr * :sqr) < :nua) then begin
sqr = :sqr + 0.2500; -- Primeiro Quarto
if ((:sqr * :sqr) > :nua) then
begin
sqr = :sqr - 0.2500;
while ((:sqr * :sqr) <= :nua) do begin
sqr = :sqr + 0.0001;
end
end
else begin
sqr = :sqr + 0.2500; -- Segundo Quarto
if ((:sqr * :sqr) > :nua) then
begin
sqr = :sqr - 0.2500;
while ((:sqr * :sqr) <= :nua) do begin
sqr = :sqr + 0.0001;
end
end
else begin -- Terceiro Quarto
sqr = :sqr + 0.2500;
while ((:sqr * :sqr) > :nua) do begin
sqr = :sqr - 0.0500;
end
while ((:sqr * :sqr) <= :nua) do begin
sqr = :sqr + 0.0001;
end
end
end
end
if ((:sqr * :sqr) > :nua) then
sqr = :sqr - 0.0001;
end
suspend;
end
========================================
CREATE PROCEDURE FU_STRZERO(
WVAR VARCHAR(8192),
WTAM INTEGER)
RETURNS (
R_STRZERO VARCHAR(8192))
AS
declare variable wint integer;
begin
/*
Devolve WVAR com tamanho WTAM só que com zeros à esquerda
*/
select r_Len from Fu_Len(:wvar) into :wint;
wint = 255 - :wint;
select r_Replicate from Fu_Replicate(:wint, '0') into r_StrZero;
r_StrZero = r_StrZero || :wvar; -- 255 Bytes
select r_Sright from Fu_S_Right(:r_strzero, :wtam) into :r_strzero;
suspend;
end
======================================================
CREATE PROCEDURE FU_S_LEFT(
WVAR VARCHAR(8192),
WQTD INTEGER)
RETURNS (
R_SLEFT VARCHAR(8192))
AS
DECLARE VARIABLE K INTEGER;
begin
/*
Devolve WQTD caracteres à esquerda de um string
*/
select r_Len from Fu_Len(:wvar) into :k;
r_sleft = '';
while ((:wvar is not null) and (:k > 0) and (:wqtd > 0)) do begin
r_sleft = r_sleft || substring(:wvar from 1 for 1);
wvar = substring(:wvar from 2 for 8191);
k = :k - 1;
wqtd = :wqtd - 1;
end
suspend;
end
================================================
CREATE PROCEDURE FU_S_RIGHT(
WVAR VARCHAR(8192),
WQTD INTEGER)
RETURNS (
R_SRIGHT VARCHAR(8192))
AS
DECLARE VARIABLE K INTEGER;
begin
/*
Devolve WQTD caracteres à direita de um string
*/
if (:wvar is not null) then begin
select r_Len from Fu_Len(:wvar) into :k;
if (:wqtd >= :k) then
r_sright = :wvar;
else
select r_Copy from Fu_Copy(:wvar, ((:k - :wqtd) + 1), :wqtd) into
:r_sright;
end
suspend;
end
=============================================
CREATE PROCEDURE FU_TEMPO_BETWEEN(
INI TIMESTAMP,
FIM TIMESTAMP)
RETURNS (
DIAS INTEGER,
HORA INTEGER,
MINU INTEGER,
SEGU INTEGER)
AS
DECLARE VARIABLE TEMP NUMERIC(18,7);
BEGIN
/*
Devolve dias, horas, minutos e segundos entre 2 TS
*/
-- Inicializa variáveis
dias = 0;
hora = 0;
minu = 0;
segu = 0;
-- Temp armazena a diferenca do periodo, em dias e frações de dias
temp = (fim - ini);
-- Pega o numero de dias - parte inteira
if (:temp > 0) then
dias = temp - 0.5;
else
dias = temp;
-- extraí os dias do timestamp, deixando apenas hora/min/seg'
temp = temp - dias;
-- Um dia tem 86.400 segundos, assim transformamos o valor
-- que temos em total em segundos
temp = temp * 86400;
-- Uma hora tem 3.600 segundos
hora = (temp / 3600);
if (hora > 0) then
hora = hora - 0.5;
-- Temp vale agora minutos e segundos
temp = temp - (hora * 3600);
-- Um minuto tem 60 segundos
minu = (temp / 60);
if (minu > 0) then
minu = minu - 0.5;
-- Para finalizar extrai os segundos
segu = temp - (minu * 60);
suspend;
end
===========================================
CREATE PROCEDURE FU_TRIM(
WVAR VARCHAR(8192))
RETURNS (
R_TRIM VARCHAR(8192))
AS
DECLARE VARIABLE J INTEGER;
DECLARE VARIABLE K INTEGER;
DECLARE VARIABLE I INTEGER;
declare variable s varchar(1);
begin
/*
Retira espaços à direita e à esquerda de um string
*/
j = 0;
select r_Len from Fu_Len(:wvar) into :k;
r_trim = '';
while ((:wvar is not null) and (:k > 0)) do begin
if (:j > 0) then
r_trim = r_trim || substring(:wvar from 1 for 1);
else if (substring(:wvar from 1 for 1) <> ' ') then begin
r_trim = r_trim || substring(:wvar from 1 for 1);
j = 1;
end
wvar = substring(:wvar from 2 for 8191);
k = :k - 1;
end
wvar = :r_trim;
select r_Len from Fu_Len(:wvar) into :i;
if ((:i < 2) or (:wvar = ' ')) then
r_trim = '';
else begin
while ((:i > 0) and (:wvar is not null)) do begin
select r_Sright from Fu_S_Right(:wvar, 1) into :s;
if (:s = ' ') then
begin
select r_copy from Fu_copy(:wvar, 1, (:i - 1)) into :wvar;
i = :i - 1;
end
else
break;
end
r_trim = :wvar;
end
suspend;
end
====================================================
CREATE PROCEDURE FU_TROCA_BYTES(
WSTR VARCHAR(1024),
WSUB VARCHAR(255),
WTRO VARCHAR(255))
RETURNS (
R_TROCA_BYTES VARCHAR(1024))
AS
declare variable trab varchar(1024);
declare variable xtra varchar(1024);
declare variable wtra varchar(1024);
declare variable wint smallint;
declare variable tsub smallint;
declare variable tstr smallint;
begin
/*
Troca em WSTR todas as ocorrências de WSUB por WTRO encontradas
*/
if (:wsub = :wtro) then
r_troca_bytes = :wstr;
else if (:wtro is null) then
r_troca_bytes = :wstr;
else if (:wsub is null) then
r_troca_bytes = :wtro;
else begin
select r_len from Fu_len(:wstr) into :tstr;
select r_len from Fu_len(:wsub) into :tsub;
wtra = :wstr;
wint = 1;
if (:tsub > 255) then begin
tsub = 255;
wsub = substring(:wsub from 1 for 255);
wtro = substring(:wtro from 1 for 255); -- 1234567890
end -- xxxxyyxxxx
while (:wint > 0) do begin
select result from Fu_pos(:wsub, :wtra) into :wint;
if (:wint > 0) then begin
select r_copy from Fu_copy(:wtra, 1, (:wint - 1)) into :trab;
select r_copy from Fu_copy(:wtra, (:wint + :tsub), 1024) into
:xtra;
wtra = :trab || :wtro || :xtra;
end
end
r_troca_bytes = :wtra;
end
suspend;
end
=================================================
CREATE PROCEDURE FU_VALIDACGC(
WCGC VARCHAR(14))
RETURNS (
OK CHAR(1))
AS
declare variable trab varchar(2);
declare variable wcal varchar(12);
declare variable wsom integer;
declare variable wdig smallint;
declare variable wint smallint;
begin
/*
Valida um CNPJ
*/
select r_OnlyDigit from Fu_OnlyDigit(:wcgc) into :wcgc;
wsom = 0;
wcal = substring(:wcgc from 1 for 12);
wint = 1;
while (:wint <= 4) do begin
select r_Copy from Fu_Copy(:wcgc, :wint, 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (6 - :wint);
wint = :wint + 1;
end
wint = 1;
while (:wint <= 8) do begin
select r_Copy from Fu_Copy(:wcgc, (:wint + 4), 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (10 - :wint);
wint = :wint + 1;
end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
wcal = :wcal || '0';
else
wcal = :wcal || cast(:wdig as char(1));
wsom = 0;
wint = 1;
while (:wint <= 5) do begin
select r_Copy from Fu_Copy(:wcgc, :wint, 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (7 - :wint);
wint = :wint + 1;
end
wint = 1;
while (:wint <= 8) do begin
select r_Copy from Fu_Copy(:wcgc, (:wint + 5), 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (10 - :wint);
wint = :wint + 1;
end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
wcal = :wcal || '0';
else
wcal = :wcal || cast(:wdig as char(1));
if (:wcgc <> :wcal) then
ok = 'N';
else
ok = 'S';
suspend;
end
============================================
CREATE PROCEDURE FU_VALIDACPF(
WCPF VARCHAR(11))
RETURNS (
OK CHAR(1))
AS
declare variable trab varchar(2);
declare variable wcal varchar(12);
declare variable wsom integer;
declare variable wdig smallint;
declare variable wint smallint;
begin
/*
Valida um CPF
*/
select r_OnlyDigit from Fu_OnlyDigit(:wcpf) into :wcpf;
wsom = 0;
wcal = substring(:wcpf from 1 for 9);
wint = 1;
while (:wint <= 9) do begin
select r_Copy from Fu_Copy(:wcpf, :wint, 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (11 - :wint);
wint = :wint + 1;
end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
wcal = :wcal || '0';
else
wcal = :wcal || cast(:wdig as char(1));
wsom = 0;
wint = 1;
while (:wint <= 10) do begin
select r_Copy from Fu_Copy(:wcpf, :wint, 1) into :trab;
wsom = :wsom + cast(:trab as smallint) * (12 - :wint);
wint = :wint + 1;
end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
wcal = :wcal || '0';
else
wcal = :wcal || cast(:wdig as char(1));
if (:wcpf <> :wcal) then
ok = 'N';
else
ok = 'S';
suspend;
end
==============================================
Os IIFs abaixo trabalham conforme o IIF do Delphi só que
recebendo e devolvendo a natureza de cada variável........
Use quem preferir
----------------------------------------------------------
CREATE PROCEDURE FU_IIF_DEC(
STR1 DECIMAL(16,4),
WSIG VARCHAR(2),
STR2 DECIMAL(16,4),
STR3 DECIMAL(16,4),
STR4 DECIMAL(16,4))
RETURNS (
R_DEC DECIMAL(16,4))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_dec = :str3;
else
r_dec = :str4;
end
suspend;
end
=======================================
CREATE PROCEDURE FU_IIF_INT(
STR1 INTEGER,
WSIG VARCHAR(2),
STR2 INTEGER,
STR3 INTEGER,
STR4 INTEGER)
RETURNS (
R_INT INTEGER)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_int = :str3;
else
r_int = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_int = :str3;
else
r_int = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_int = :str3;
else
r_int = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_int = :str3;
else
r_int = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_int = :str3;
else
r_int = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_int = :str3;
else
r_int = :str4;
end
suspend;
end
============================================
CREATE PROCEDURE FU_IIF_INT_DEC(
STR1 INTEGER,
WSIG VARCHAR(2),
STR2 INTEGER,
STR3 DECIMAL(16,4),
STR4 DECIMAL(16,4))
RETURNS (
R_INT_DEC DECIMAL(16,4))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_int_dec = :str3;
else
r_int_dec = :str4;
end
suspend;
end
=============================================
CREATE PROCEDURE FU_IIF_INT_SMI(
STR1 INTEGER,
WSIG VARCHAR(2),
STR2 INTEGER,
STR3 SMALLINT,
STR4 SMALLINT)
RETURNS (
R_INT_SMI SMALLINT)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_int_smi = :str3;
else
r_int_smi = :str4;
end
suspend;
end
=======================================
CREATE PROCEDURE FU_IIF_INT_STR(
STR1 INTEGER,
WSIG VARCHAR(2),
STR2 INTEGER,
STR3 VARCHAR(255),
STR4 VARCHAR(255))
RETURNS (
R_INT_STR VARCHAR(255))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_int_str = :str3;
else
r_int_str = :str4;
end
suspend;
end
===============================================
CREATE PROCEDURE FU_IIF_SMI(
STR1 SMALLINT,
WSIG VARCHAR(2),
STR2 SMALLINT,
STR3 SMALLINT,
STR4 SMALLINT)
RETURNS (
R_SMI SMALLINT)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_smi = :str3;
else
r_smi = :str4;
end
suspend;
end
========================================
CREATE PROCEDURE FU_IIF_SMI_DEC(
STR1 SMALLINT,
WSIG VARCHAR(2),
STR2 SMALLINT,
STR3 DECIMAL(16,4),
STR4 DECIMAL(16,4))
RETURNS (
R_SMI_DEC DECIMAL(16,4))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_smi_dec = :str3;
else
r_smi_dec = :str4;
end
suspend;
end
=========================================
CREATE PROCEDURE FU_IIF_SMI_INT(
STR1 SMALLINT,
WSIG VARCHAR(2),
STR2 SMALLINT,
STR3 INTEGER,
STR4 INTEGER)
RETURNS (
R_SMI_INT INTEGER)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_smi_int = :str3;
else
r_smi_int = :str4;
end
suspend;
end
============================================
CREATE PROCEDURE FU_IIF_SMI_STR(
STR1 SMALLINT,
WSIG VARCHAR(2),
STR2 SMALLINT,
STR3 VARCHAR(255),
STR4 VARCHAR(255))
RETURNS (
R_SMI_STR VARCHAR(255))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_smi_STR = :str3;
else
r_smi_STR = :str4;
end
suspend;
end
=============================================
CREATE PROCEDURE FU_IIF_STR(
STR1 VARCHAR(255),
WSIG VARCHAR(2),
STR2 VARCHAR(255),
STR3 VARCHAR(255),
STR4 VARCHAR(255))
RETURNS (
R_STR VARCHAR(255))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_str = :str3;
else
r_str = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_str = :str3;
else
r_str = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_str = :str3;
else
r_str = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_str = :str3;
else
r_str = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_str = :str3;
else
r_str = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_str = :str3;
else
r_str = :str4;
end
suspend;
end
============================================
CREATE PROCEDURE FU_IIF_STR_DEC(
STR1 VARCHAR(255),
WSIG VARCHAR(2),
STR2 VARCHAR(255),
STR3 DECIMAL(16,4),
STR4 DECIMAL(16,4))
RETURNS (
R_STR_DEC DECIMAL(16,4))
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_str_dec = :str3;
else
r_str_dec = :str4;
end
suspend;
end
====================================================
CREATE PROCEDURE FU_IIF_STR_INT(
STR1 VARCHAR(255),
WSIG VARCHAR(2),
STR2 VARCHAR(255),
STR3 INTEGER,
STR4 INTEGER)
RETURNS (
R_STR_INT INTEGER)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_str_int = :str3;
else
r_str_int = :str4;
end
suspend;
end
================================================
CREATE PROCEDURE FU_IIF_STR_SMI(
STR1 VARCHAR(255),
WSIG VARCHAR(2),
STR2 VARCHAR(255),
STR3 SMALLINT,
STR4 SMALLINT)
RETURNS (
R_STR_SMI SMALLINT)
AS
begin
if (:wsig = '=') then
begin
if (:str1 = :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
else if (:wsig = '<') then
begin
if (:str1 < :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
else if (:wsig = '>') then
begin
if (:str1 > :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
else if (:wsig = '>=') then
begin
if (:str1 >= :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
else if (:wsig = '<=') then
begin
if (:str1 <= :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
else if (:wsig = '<>') then begin
if (:str1 <> :str2) then
r_str_smi = :str3;
else
r_str_smi = :str4;
end
suspend;
end

Você também pode gostar