Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Базы данных
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 26.10.2011, 18:46
dima_10 dima_10 вне форума
Прохожий
 
Регистрация: 06.04.2011
Сообщения: 1
Репутация: 10
По умолчанию вычисляемые поля

Помогите пожалуйста. есть две таблицы ostatki, potrebnost

таблицы ostatki, potrebnost
имеют поля (diametr, gost , ves). Нужно если diametr и gost в одной таблице равны diametr и gost в другой то ves из одной таблице должен вычитаться из другой и записыватся в поле itog. Вот текст. Подскажите ,что не так
Код:
procedure TForm1.Button2Click(Sender: TObject);

begin
form1.ADOtable1.first;
while form1.ADOtable1.Eof do
begin
if (ADOtable1diametr.Value=form1.ADOtable2diametr1.Value)and
 (ADOtable1gost.Value= ADOtable2gost1.Value) 
  then
 // ADOtable1rezult.Value:=ADOtable2ves1.Value-ADOtable1ves.Value  ;
  ADOtable1itog.Value:=ADOtable2ves1.Value - ADOtable1ves.Value;

form1.ADOtable1.next;
end;end;
Админ: Пользуемся тегами для оформления кода!

Спасибо за помощь

Последний раз редактировалось Admin, 26.10.2011 в 18:52.
Ответить с цитированием
  #2  
Старый 26.10.2011, 19:56
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

А на уровне SQL это нельзя сделать?

Код:
select o.diametr, o.gost, (o.ves - p.ves) as itog
from ostatki o left join potrebnost p on o.gost=p.gost and o.diametr = з.diametr
Ответить с цитированием
  #3  
Старый 28.10.2011, 16:25
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

есть 2 подхода
1. на уровне SQL- пишешь SQL процедуру
2. на уровне пользовательской подключаемой библиотеки

вечером покажу.
Ответить с цитированием
  #4  
Старый 29.10.2011, 01:41
chainik chainik вне форума
Начинающий
 
Регистрация: 30.06.2008
Сообщения: 140
Репутация: 8882
По умолчанию

/*---вот объявление функций пользователя.
Это оформляется в виде 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 следует помещать функции сложные. Они пишутся на языках высокого уровня и потому просты в отладке.
Оформмять твои специфические функции как триггеры следует тогда, когда они достаточно просты
и кроме того предвидится необходимость их изменять. Это так называемые Бизнес-правила.
Например, как триггер следует оформить функцию вычета подоходного налогга.
Если правила исчисления подоходного налога изменились- ты просто в твоей БД изменяешь эту функцию- и она
автоматически действует для всех пользователей.
*/
Ответить с цитированием
  #5  
Старый 29.10.2011, 08:46
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Тов, Чайник, а вам не кажется, что вас нетуда понесло???
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 01:16.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter