/*---вот объявление функций пользователя.
Это оформляется в виде DLL. Я привожу этот пример только как рыбу.
Обрати внимание на способ передачи параметров- cdecl.
Это обязательное условие.
Этот текст надо оформить в виде DLL- библиотеки и поместить ее в
каталог C:\Interbase\Udf
*'/
Код:
library UdfMetrolog;
uses
SysUtils, DateUtils;
function GetYear(var Dt:double):smallint;cdecl;
begin
try
GetYear:=YearOf(Dt);
except
GetYear:=9999
end
end;
function GetMonth(var Dt:double):smallint;cdecl;
begin
try
Result:=MonthOf(Dt);
except
Result:=-1
end
end;
function AddMonth(var Dt:double;var NumbOfMonth:integer):double;cdecl;
begin
try
Result:=IncMonth(Dt,NumbOfMonth);
except
Result:=-1
end
end;
exports
AddMonth,
GetMonth,
GetYear;
begin
end.
После того как ты изготовил DLL с твоими функциями пользователя
на них можно ссылаться в тексте описания БД.
Для этого надо сделать внешние ссылки на эти функции, как это указано ниже.
Теперь твои функции можно применять также как и стандартные.
Надо сказать что такую возможность предоставляют не все базы данныз.
Лично я использую InterBase/FireBird, где все это есть.
*/
Код:
DECLARE EXTERNAL FUNCTION ADDMONTH DOUBLE PRECISION, INTEGER
RETURNS DOUBLE PRECISION BY VALUE
ENTRY_POINT 'AddMonth' MODULE_NAME 'UdfMetrolog';
DECLARE EXTERNAL FUNCTION GETMONTH DOUBLE PRECISION
RETURNS SMALLINT BY VALUE
ENTRY_POINT 'GetMonth' MODULE_NAME 'UdfMetrolog';
DECLARE EXTERNAL FUNCTION GETYEAR DOUBLE PRECISION
RETURNS SMALLINT BY VALUE
ENTRY_POINT 'GetYear' MODULE_NAME 'UdfMetrolog';
///// 2 /////////////////
Теперь о втором способе.
Можно в самой БД создать некое свойство, которое позволяет прямо по ходу дела
анализировать ситуацию и соответственно ее обрабатывать. Это триггеры- специальные процедуры,
внедренные в базу данных и запускающиеся автомтически при наступлении определенных событий в БД.
Например, процедура Workks_trig_ins (см ниже) автоматически запустится ПЕРЕД вставкой новой строки
в таблицу Works.
Код:
*--------------------------------------------------------------------------------------------------
генератор номеров свидетельств в пределах 1 года для таблицы Works
VidDocum IN (' - ','Сертифик. о калибр.','Свидет. о повер.','Извещ. о непригодн.','Акт на спис.')),
---------------------------------------------------------------------------------------------------*/
CREATE TRIGGER Works_trig_ins FOR Works
ACTIVE BEFORE INSERT
AS
DECLARE VARIABLE Yr SMALLINT;
DECLARE VARIABLE Yr2 SMALLINT;
BEGIN
Yr2=extract(year from CURRENT_DATE);
/* свидетельство */
IF (NOT(NEW.Svidet IS NULL)) THEN
BEGIN
SELECT GETYEAR(Dat) FROM Works
WHERE (Dat=(SELECT MAX(Dat) FROM Works
WHERE (VidDocum = NEW.VidDocum)))
INTO :Yr;
IF (NEW.VidDocum='Сертифик. о калибр.') then
BEGIN
NEW.NumSvidet_Yr = GEN_ID(Works_Kal_Yr_GEN,1);
IF (:Yr <> :Yr2) THEN
NEW.NumSvidet_Yr = GEN_ID(Works_Kal_Yr_GEN,1-NEW.NumSvidet_Yr);
END
IF (NEW.VidDocum='Свидет. о повер.') then
BEGIN
NEW.NumSvidet_Yr = GEN_ID(Works_Pov_Yr_GEN,1);
IF (:Yr <> :Yr2) THEN
NEW.NumSvidet_Yr = GEN_ID(Works_Pov_Yr_GEN,1-NEW.NumSvidet_Yr);
END
IF (NEW.VidDocum='Извещ. о непригодн.') then
BEGIN
NEW.NumSvidet_Yr = GEN_ID(Works_Negodn_Yr_GEN,1);
IF (:Yr <> :Yr2) THEN
NEW.NumSvidet_Yr = GEN_ID(Works_Negodn_Yr_GEN,1-NEW.NumSvidet_Yr);
END
IF (NEW.VidDocum='Акт на спис.') then
BEGIN
NEW.NumSvidet_Yr = GEN_ID(Works_Spisan_Yr_GEN,1);
IF (:Yr <> :Yr2) THEN
NEW.NumSvidet_Yr = GEN_ID(Works_Spisan_Yr_GEN,1-NEW.NumSvidet_Yr);
END
END
END!
/*
Итак, после всего этого база данных перестает быть просто хранилищем,
а приобретает определенный интеллект, чем программист должен уметь пользоваться.
После того как программист заложил в БД функции, она приобретает способность производить первичную обработку информации
и уже находится в состоянии, когда может по требованию пользователя выдать нужную информацию
(перед тем ее обработав и представив в нужном виде!).
Несколько советов
Эти 2 способа в какой- то мере конкурируют между собой. Какой из них избрать для достижения заданной цели-
решает программист.
Мой совет
В DLL следует помещать функции сложные. Они пишутся на языках высокого уровня и потому просты в отладке.
Оформмять твои специфические функции как триггеры следует тогда, когда они достаточно просты
и кроме того предвидится необходимость их изменять. Это так называемые Бизнес-правила.
Например, как триггер следует оформить функцию вычета подоходного налогга.
Если правила исчисления подоходного налога изменились- ты просто в твоей БД изменяешь эту функцию- и она
автоматически действует для всех пользователей.
*/