Fórum UDF para calcular Idade não funciona #59202
02/12/2007
0
Bom dia a todos.
Estou usando o Firebird 2.0.3.12981.
Tenho o seguinte cenário:
Criei uma UDF (braUDF.dll) bem simples para calcular a idade dos meus clientes como segue abaixo:
É importante informar que testei essa dll usando o um novo aplicativo Delphi e tudo funciona perfeitamente, ouseja, a função está escrita corretamente (o problema será quando executar usando o servidor do banco de dados).
Pois bem!
Copiei a DLL para o diretório UDF do Firebird e a registrei no meu banco de dados usando o IBExpert segundo o código abaixo:
Até aí tudo ok.
Chegou a hora de testar a função. Então uso o próprio IBExpert para fazer a seguinte pesquisa na minha tabela de clientes:
E aí começa o meu tormento:
todos os meus clintes têm 107 anos. ou seja, o Firebird está passando como parâmetro para a função UDF CalculaIdade a data ´30/12/1899´ para TODOS os registros.
Alguém conseguiria detectar onde estou errando?
Agradeço qualquer dica.
Obrigado e bom trabalho a todos.
Estou usando o Firebird 2.0.3.12981.
Tenho o seguinte cenário:
Criei uma UDF (braUDF.dll) bem simples para calcular a idade dos meus clientes como segue abaixo:
unit UnitUDF;
interface
uses
SysUtils, DateUtils;
function CalculaIdade(DATA: TDateTime): Integer; export;Stdcall;
implementation
{Função para calcular a idade atual a partir da data do nascimento}
function CalculaIdade(DATA: TDateTime): Integer;
VAR COMPLETO : Integer;
begin
result := 0;
COMPLETO := YearOf(Date) - YearOf(DATA);
if MonthOf(DATE) > MonthOf(DATA) then
result := COMPLETO;
if MonthOf(DATE) < MonthOf(DATA) then
result := COMPLETO - 1;
if MonthOf(DATE) = MonthOf(DATA) then
if DayOf(DATE) >= DayOf(DATA) then
result := COMPLETO
else
result := COMPLETO - 1;
end;
end.
É importante informar que testei essa dll usando o um novo aplicativo Delphi e tudo funciona perfeitamente, ouseja, a função está escrita corretamente (o problema será quando executar usando o servidor do banco de dados).
Pois bem!
Copiei a DLL para o diretório UDF do Firebird e a registrei no meu banco de dados usando o IBExpert segundo o código abaixo:
DECLARE EXTERNAL FUNCTION CALCULAIDADE DATE RETURNS INTEGER BY VALUE ENTRY_POINT ´CalculaIdade´ MODULE_NAME ´braUDF´;
Até aí tudo ok.
Chegou a hora de testar a função. Então uso o próprio IBExpert para fazer a seguinte pesquisa na minha tabela de clientes:
select codigo,nome, nascimento, calculaidade(nascimento) from CLIENTES
E aí começa o meu tormento:
todos os meus clintes têm 107 anos. ou seja, o Firebird está passando como parâmetro para a função UDF CalculaIdade a data ´30/12/1899´ para TODOS os registros.
Alguém conseguiria detectar onde estou errando?
Agradeço qualquer dica.
Obrigado e bom trabalho a todos.
Brasidata
Curtir tópico
+ 0
Responder
Posts
03/12/2007
Gandalf.nho
Para fazer UDFs para IB/FB envolvendo datas é necessário um certo tratamento dos parâmetros, devido ao formato usado. Dê uma olhada nesse link, que tem as explicações para isso: http://www.ibphoenix.com/main.nfs?a=ibphoenix&page=ibp_howto2
Responder
Gostei + 0
03/12/2007
Brasidata
Obrigado pela atenção gandalf.nho,
Li o material do link, mas achei a coisa realmente complexa para DATAS além de ser direcionado mais especificamente ao INTERBASE.
Tentei refazer minha UDF com as adaptações necessárias para o Firebird + BDS2006 (substituindo o tipo LONG por Int64 e as dlls do interbase, etc...) e mesmo assim, a ´coisa´ não funcionou tão bem quanto eu esperava.
Portanto, optei por abandonar temporariamente a idéia da UDF e parti para a solução através de uma Stored Procedure :
Obrigado , mais uma vez, pela dica.
Li o material do link, mas achei a coisa realmente complexa para DATAS além de ser direcionado mais especificamente ao INTERBASE.
Tentei refazer minha UDF com as adaptações necessárias para o Firebird + BDS2006 (substituindo o tipo LONG por Int64 e as dlls do interbase, etc...) e mesmo assim, a ´coisa´ não funcionou tão bem quanto eu esperava.
Portanto, optei por abandonar temporariamente a idéia da UDF e parti para a solução através de uma Stored Procedure :
create procedure SP_AgeOf(NASCIMENTO Date) returns (IDADE integer) as declare variable MesNasc Integer; declare variable DiaNasc Integer; declare variable MesAtual Integer; declare variable DiaAtual Integer; begin MesNasc = extract(month from NASCIMENTO); DiaNasc = extract(day from NASCIMENTO); MesAtual = extract(month from current_date); DiaAtual = extract(day from current_date); IDADE = extract(year from current_date) - extract(year from NASCIMENTO); if ((MesNasc > MesAtual) or ((MesNasc = MesAtual) and (DiaNasc > DiaAtual))) then IDADE = IDADE - 1; suspend; end;
Obrigado , mais uma vez, pela dica.
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)