Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > БД в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 26.08.2014, 06:36   #1
fobass
Форумчанин
 
Регистрация: 05.06.2008
Сообщений: 100
По умолчанию Вызов ХП по таймеру IBQuery

Привет всем. Почему форма виснет при вызове хранимых процедур. ХП вызывается по таймеру т.е каждую секунду.
База Firebird 2.1; подключение через IBDatabase, IBDatabase,IBTransaction, IBQuery.
Вызов ХП
Код:
procedure TForm1.Timer2Timer(Sender: TObject);
begin
T1 := Now;
if  InitDataBase then
try
  form1.IBQuery1.Transaction.StartTransaction;
  form1.IBQuery1.SQL.Clear;
  form1.IBQuery1.SQL.Add('ExECUTE PROCEDURE GET_F0 :Param1, :Param2');
  form1.IBQuery1.ParamByName('Param1').AsFloat:=Random(100);
  form1.IBQuery1.ParamByName('Param2').AsFloat:=Random(100);
  form1.IBQuery1.ExecSQL;
  form1.Label_P_0.Caption:=FloatToStr(ROUND(form1.IBQuery1.Current.ByName('P').AsFloat));
  form1.Label_Q_0.Caption:=FloatToStr(form1.IBQuery1.Current.ByName('Q').AsFloat);
  form1.Label_cosfi_0.Caption:=FloatToStr(form1.IBQuery1.Current.ByName('COS_FI').AsFloat);
  form1.Label_Tok_0.Caption:=FloatToStr(form1.IBQuery1.Current.ByName('TOK').AsFloat);
  IBQuery1.Transaction.Commit;
except
  IBQuery1.Transaction.Rollback;
  end;
MS := MilliSecondsBetween(Now, T1);
form1.Label12.Caption:=IntToStr(MS);
ХП
Код:
CREATE PROCEDURE GET_F0 (
  SIGNAL_P   FLOAT,
  SIGNAL_Q   FLOAT
)
RETURNS (
  P        FLOAT,
  Q        FLOAT,
  COS_FI   FLOAT,
  TOK      FLOAT
)
AS
DECLARE lP FLOAT;
DECLARE lQ FLOAT;
DECLARE lCOS_FI FLOAT;
DECLARE lTOK FLOAT;
DECLARE lSIGNAL_P FLOAT;
DECLARE lSIGNAL_Q FLOAT;
DECLARE lA FLOAT;
DECLARE lR FLOAT;
DECLARE lRN_P FLOAT;
DECLARE lRN_Q FLOAT;
DECLARE lTT FLOAT;
DECLARE lTN_1 FLOAT;
DECLARE lU_RUGHT FLOAT;
DECLARE lS FLOAT;

BEGIN
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=75 INTO lA;
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=24 INTO lRN_P;
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=0 INTO lTT;
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=72 INTO lTN_1;
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=94 INTO lR;
      SELECT DATAVALUES FROM CONFIG_RATIO_FIDERS WHERE ID=30 INTO lRN_Q;
      SELECT FIRST 1 U_LEFT FROM BUS ORDER BY KEYTIME DESC INTO lU_RUGHT;

 IF (:SIGNAL_P >= 0) THEN
    BEGIN
      lSIGNAL_P=:SIGNAL_P/10+lA;
      IF (lSIGNAL_P>0) THEN
          BEGIN
            lP=(((((lSIGNAL_P/lRN_P)*500)/5)*lTT*lTN_1)/1000);
            P=lP*100*SQRT(3)/100;
          END
      ELSE
      IF (lSIGNAL_P=0) THEN
          BEGIN
             P=0;
             lP=0;
          END
      ELSE
      IF (lSIGNAL_P=NULL) THEN
          BEGIN
             P=0;
             lP=0;
          END
    END
IF (:SIGNAL_Q >= 0) THEN
    BEGIN
      lSIGNAL_Q=:SIGNAL_Q/10+lR;
      IF (lSIGNAL_Q>0) THEN
          BEGIN
            lQ=(((((lSIGNAL_Q/lRN_Q)*500)/5)*lTT*lTN_1)/1000);
            Q=lQ*100*SQRT(3)/100;
          END
      ELSE
      IF (lSIGNAL_Q=0) THEN
          BEGIN
             Q=0;
             lQ=0;
          END
      ELSE
      IF (lSIGNAL_Q=NULL) THEN
          BEGIN
             Q=0;
             lQ=0;
          END
    END
--Переделать токи пиздят
TOK=SQRT(lP*lP+lQ*lQ)/(lU_RUGHT/1000);

 IF (TOK>0) THEN
    BEGIN
      lCOS_FI=P/SQRT(P*P+Q*Q);
    END
 IF (TOK=0) THEN
    BEGIN
      lCOS_FI=0;
    END
 IF ((P+Q)<1) THEN
    BEGIN
      lCOS_FI=0;
    END
 COS_FI=lCOS_FI*100/100;
 IF (COS_FI=1) THEN
    BEGIN
     Q=0;
    END
INSERT INTO F0(KEYTIME,P,Q,COS_FI,TOK) VALUES(CURRENT_TIMESTAMP,:P,:Q,:COS_FI,:TOK);

SUSPEND;
--EXECUTE PROCEDURE PROCADDRECORDF0(CURRENT_TIMESTAMP, P, Q,COS_FI,TOK);
END

Последний раз редактировалось Stilet; 26.08.2014 в 08:05.
fobass вне форума Ответить с цитированием
Старый 26.08.2014, 08:07   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
по таймеру т.е каждую секунду
Ничесее... Ото потому и висит что частота такая. Не успеет отработать один вызов, а ты его другим нагружаешь.
Зачем тут таймер нужен вообще?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 26.08.2014, 08:11   #3
mirkul
Пользователь
 
Регистрация: 16.07.2014
Сообщений: 62
Сообщение

Согласен с Stilet.

И еще лудше использовать IBStoreProc, а не IBQuery
mirkul вне форума Ответить с цитированием
Старый 26.08.2014, 08:16   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
еще лудше использовать IBStoreProc, а не IBQuery
Та это не мае значення. Т.е. там разница не особо большая и важная.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 26.08.2014, 08:27   #5
fobass
Форумчанин
 
Регистрация: 05.06.2008
Сообщений: 100
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Ничесее... Ото потому и висит что частота такая. Не успеет отработать один вызов, а ты его другим нагружаешь.
Зачем тут таймер нужен вообще?
Таймер опрашивает контроллер, вместо Random
PHP код:
 form1.IBQuery1.ParamByName('Param1').AsFloat:=Random(100);
 
form1.IBQuery1.ParamByName('Param2').AsFloat:=Random(100); 
будет передаваться значение с COM порта.

планировал вызвать 23 ХП на одном таймере)

Цитата:
Сообщение от Stilet Посмотреть сообщение
Та это не мае значення. Т.е. там разница не особо большая и важная.
IBStoreProc отрабатывает медленнее чем IBQuery

Последний раз редактировалось Stilet; 26.08.2014 в 09:45.
fobass вне форума Ответить с цитированием
Старый 26.08.2014, 09:50   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
планировал вызвать 23 ХП на одном таймере)

Даже не знаю что сказать... Мысль только одна: Не делай так.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 26.08.2014, 11:10   #7
fobass
Форумчанин
 
Регистрация: 05.06.2008
Сообщений: 100
По умолчанию

Разделил программу на клиент и сервер, создал две хранимки GET_F0 и SET_F0. Сервер считывает данные с КОМ и передает на ХП SET_F0 - где вычисляет коэффициенты и записывает в таблицу F0. Клиент вызывает ХП GET_F0 - где
Код:
CREATE PROCEDURE GET_F0
RETURNS (
  LP        FLOAT,
  LQ        FLOAT,
  LCOS_FI   FLOAT,
  LTOK      FLOAT
)
AS
BEGIN
      SELECT FIRST 1 P FROM F0 ORDER BY KEYTIME DESC INTO lP;
      SELECT FIRST 1 Q FROM F0 ORDER BY KEYTIME DESC INTO lQ;
      SELECT FIRST 1 COS_FI FROM F0 ORDER BY KEYTIME DESC INTO lCOS_FI;
      SELECT FIRST 1 TOK FROM F0 ORDER BY KEYTIME DESC INTO lTOK;
SUSPEND;
END
;

Последний раз редактировалось Stilet; 26.08.2014 в 11:43.
fobass вне форума Ответить с цитированием
Старый 08.09.2014, 16:56   #8
vovs
Новичок
Джуниор
 
Регистрация: 26.03.2013
Сообщений: 2
По умолчанию

1. Логично выключить таймер до окончание выполнения запросов в базу.
в начале постава Timer1.Enabled:=False;
в конце Timer1.Enabled:=True;
2. Попробуй ещё antifreeze кинуть на форму.
vovs вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Чтение из БД (IBQuery) Harikolo БД в Delphi 4 30.10.2010 15:15
Динамический запрос IBQuery Liones БД в Delphi 5 06.08.2010 06:44
Ошибка в IBQuery.SQL Art_ БД в Delphi 7 12.05.2009 00:44
Filter в IBQuery Yurk@ БД в Delphi 3 23.01.2009 23:26