Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.10;
Скачать: CL | DM;

Вниз

Почему то упорно не работает UDF   Найти похожие ветки 

 
S@shka ©   (2004-09-15 02:59) [0]

function GetNextHour (var CurrentHour : TDateTime) : PChar; cdecl; export
const
onehour = 1/24;
var
t : TDateTime;
temp : String;
begin
 t := CurrentHour + oneHour;
 temp := FormatDateTime ("dd.mm.yyyy hh",t);
 temp := temp + ":00:20";
 temp := FormatDateTime ("dd.mm.yy hh:nn:ss",CurrentHour);
 Result := malloc (length(temp) + 1);
 StrPCopy (Result,temp);
end;

и InterBase описана как
DECLARE EXTERNAL FUNCTION F_NEXTHOUR
   TIMESTAMP
RETURNS CSTRING(255) FREE_IT
ENTRY_POINT "GetNextHour" MODULE_NAME "as.dll"

на любой запрос вида
select f_nexthour ("15.09.2004 01:00:01") from RDB$database
получаем
30.12.1899 01:00:20

Не понимаю - что не так???


 
Fay ©   (2004-09-15 04:18) [1]

Иди на ibase.ru. Найдёшь там инфу о написании UDF.
Обратишь внимание, что
1) IB/FB не знают, что есть TDateTime
2) Использование тобой переменной типа String ничем не оправдано.


 
Digitman ©   (2004-09-15 08:29) [2]


> S@shka ©   (15.09.04 02:59)  


см. [1]

IB-совместимые системы используют совершенно иной формат представления даты/времени

кр.того, malloc() нежелательно (а вскоре и недопустимо будет) использовать хотя бы по соображениям кроссплатформенности ... для аллокации памяти под возвращаемый рез-т следует использовать ib_util_malloc() в составе поставляемой штатно в дистрибутиве системы библ-ки ib_utils.dll


 
S@shka ©   (2004-09-15 10:39) [3]

А как же время то передавать ???
Мне нужно в UDF передать TDateTime
и вернуть из него TDateTime + один час с округлением
до ровных часов назад
Т.е.
Input  = "15.09.2004 01:25:05"
Output = "15.09.2004 02:00:00";


 
Digitman ©   (2004-09-15 11:34) [4]

uses
 IBHeader

const

MSecsPerDay10 = MSecsPerDay * 10; // миллисекунд в сутках * 10
IBDateDelta = 15018; // разница в днях между датами Delphi и IBDatabase

//внутренняя ф-ция для преобразования даты/времени из формата IB в формат Делфи
function QuadToDate(ibd: TISC_QUAD): TDateTime;
begin
  Result:= ibd.gds_quad_high - IBDateDelta + ibd.gds_quad_low / MSecsPerDay10;
end;

//внутренняя ф-ция для преобразования даты/времени из формата Делфи в формат IB
function DateToQuad(d: TDateTime): TISC_QUAD;
var
  Days: Integer;
begin
  Days:= Trunc(d);
  Result.gds_quad_high:= Days + IBDateDelta;
  Result.gds_quad_low:= Trunc((d - Days) * MSecsPerDay10);
end;

function GetNextHour (var IBDateTime : TISC_QUAD) : PChar; cdecl;
...
var
DelphiDate : TDateTime;
...
begin
DelphiDateTime := QuadToDate(IBDateTime);
....
end;


 
Виталий Панасенко   (2004-09-15 11:52) [5]

А current_timestamp никак прикрутить нельзя и без UDF обойтись? Или я не совсем понял проблему ?


 
S@shka ©   (2004-09-15 12:50) [6]

Да проблема то вообщем сформулирована была
нужно выполнить следующее округление до ровных часов вперед
Т.е.
Input  = "15.09.2004 01:25:05"
Output = "15.09.2004 02:00:00";
а с UDF или нет все равно,
мне казалось что в UDF будет проще реализовать данную задачу


 
Digitman ©   (2004-09-15 13:08) [7]


> S@shka ©   (15.09.04 12:50) [6]


мне не оч понятно, зачем результат возвращать в виде строки ...
чем оправдано это требование ? почему не вернуть рез-т в виде того же TISC_QUAD (timestamp) ? а потому ж при реальной необходимости форматнуть этот рез-т в строку, представляющую дату/время ? ведь если параметр типа TISC_QUAD и рез-т того же типа, то  это позволит обойтись без выделения памяти под рез-т !


 
S@shka ©   (2004-09-15 13:22) [8]

Yes
именно в TimeStamp результат и нужен
я же так понимаю при возвращении результата как TIMESTAMP
необходимо выделять память так как передавать надо по ссылке
а как правильно это слелать я пока не нашел.
А вообще зачем это все нужно (может это проще можно сделать и не нужно никаких UDF брать)
Имеем табличку
Param             Time                 Value
 1              12.05.2004 11:00:01     1
 1              12.05.2004 11:01:01     1
 1              12.05.2004 11:02:11     1
 1              12.05.2004 11:03:36     1
 1              12.05.2004 12:00:01     1

И мне нужно определить, например, сумму значений
по каждому часу т.е.
time between 11:00 12:00 и т.д.
то есть для данного набора должен был выдать
 1 12.05.2004 12:00:00 4
 1 12.05.2004 13:00:00 1


 
Digitman ©   (2004-09-15 14:02) [9]


> я же так понимаю при возвращении результата как TIMESTAMP
> необходимо выделять память так как передавать надо по ссылке


нет, выделять память в случаях, когда размер параметра совпадает с размером результата, совершенно необязательно

дело в том, что при передаче факт.параметра ИБ формирует временную его копию в своей памяти и передает в UDF ссылку на него

этот врем.параметр будет уничтожет только после того как ИБ получит результат вызова UDF, чем с успехом можно и воспользоваться, записав результат в область памяти, отведенную под врем.параметр

function GetNextHour (var IBDateTime : TISC_QUAD) : PISC_QUAD; cdecl;
 function ProcessInputParameter(dt: TDateTime): TDateTime;
 begin
   ... //здесь формируешь рез-т привычным образом и по нужному алгоритму
 end;
begin
Result := @IBDateTime; //результат передаем по ссылке на область памяти, занятую вх.параметром
Result^ := DateToQuad(ProcessInputParameter(QuadToDate(IBDateTime)));
end;

DECLARE EXTERNAL FUNCTION F_NEXTHOUR
  TIMESTAMP /* параметр по дифолту передается по ссылке */
RETURNS TIMESTAMP /* результат по дифолту так же возвращается по ссылке */
ENTRY_POINT "GetNextHour" MODULE_NAME "as.dll"


 
Digitman ©   (2004-09-15 14:13) [10]


> S@shka ©   (15.09.04 13:22) [8]


ФБ свежих релизов позволяет в запросах группировки по результатам, возвращаемым из UDF

так что для твоей задачи лучше было бы возвращать из UDF значение часа в этом дне (см. ф-цию DecodeTime)

тогда в запросе можно будет использовать

... GROUP BY GetTimestampHour(SomeIBTimeStampValue)


 
S@shka ©   (2004-09-15 14:49) [11]

Большое спасибо.



Страницы: 1 вся ветка

Текущий архив: 2004.10.10;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.029 c
14-1095754445
_User_
2004-09-21 12:14
2004.10.10
OpenSource проект на Delphi (WinAPI)


1-1095934991
Дмитрий
2004-09-23 14:23
2004.10.10
Динамический массив


1-1095751011
Snip
2004-09-21 11:16
2004.10.10
Опять глупый вопрос по DLL


4-1092391573
Дмитрий Ботвин
2004-08-13 14:06
2004.10.10
Тип запуска службы


4-1094710880
turich
2004-09-09 10:21
2004.10.10
Помогите с диалап соединением