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

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

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.11.2011, 16:23   #1
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
Вопрос Не работает цикл обновления в Firebird

Добрый вечер! Не могу уже второй день понять почему не работает код ниже. Нужно вот что сделать.
1. Получить номер последней записи в БД (сделано).
2. Передать в цикле параметры в хранимую процедуру и обновить одновременно указанную таблицу значениями, полученными после выполнения хранимой процедуры.
Вот код:
Код:
//===============получение последней записи==================
  Form1.pFIBDataSet4.Close;
  Form1.pFIBDataSet4.SQLs.SelectSQL.Text:='select max(ID) as F from jurnal';
  Form1.pFIBDataSet4.Open;
  Form1.sEdit10.Text:=IntToStr(Form1.pFIBDataSet4.FieldByName('F').AsInteger);


//==============ОБНОВЛЕНИЕ ЧЕРЕЗ ХРАНИМУЮ ПРОЦЕДУРУ=======
   Form1.pFIBDataSet4.Close;
   Form1.pFIBDataSet4.Close;
   Form1.pFIBDataSet4.SQLs.SelectSQL.Text:='select OGRN from jurnal where ID > ' + Form1.sEdit10.Text;
   Form1.pFIBDataSet4.Open;
   Form1.pFIBDataSet4.First;
   Application.ProcessMessages;
   while not Form1.pFIBDataSet4.Eof do
   begin
    Form1.sp2.Close;
    Form1.sp2.Parameters.ParamByName('OGRN').Value:=Form1.pFIBDataSet4.FieldByName('OGRN').AsString;
    Form1.sp2.Open;

    Form1.pFIBDataSet4.Next;
      Form1.pFIBQuery2.SQL.Clear;
      Form1.pFIBQuery2.SQL.Add('update jurnal set REGNUMBER=:num,');
      Form1.pFIBQuery2.SQL.Add(' DATASNYT=:ds,');
      Form1.pFIBQuery2.SQL.Add(' DATAPST=:dp,');
      Form1.pFIBQuery2.SQL.Add(' KATEGORIA=:k,');
      Form1.pFIBQuery2.SQL.Add(' FIONEW=:fn,');
      Form1.pFIBQuery2.SQL.Add(' ST=:s,');
      Form1.pFIBQuery2.SQL.Add(' INN=:i');
      Form1.pFIBQuery2.SQL.Add(' where OGRN=:ogrnum and ID > ' + Form1.sEdit10.Text);
      Form1.pFIBQuery2.ParamByName('num').Value:=Form1.sp2.FieldByName('REGNUMBERU').AsString;
      Form1.pFIBQuery2.ParamByName('ds').Value:=Form1.sp2.FieldByName('DATASNYTU').AsString;
      Form1.pFIBQuery2.ParamByName('dp').Value:=Form1.sp2.FieldByName('DATAPSTU').AsString;
      Form1.pFIBQuery2.ParamByName('k').Value:=Form1.sp2.FieldByName('KATEGORIA').AsString;
      Form1.pFIBQuery2.ParamByName('fn').Value:=Form1.sp2.FieldByName('FIONEWU').AsString;
      Form1.pFIBQuery2.ParamByName('s').Value:=Form1.sp2.FieldByName('STU').AsString;
      Form1.pFIBQuery2.ParamByName('ogrnum').Value:=Form1.sp2.FieldByName('OGRNU').AsString;
      Form1.pFIBQuery2.ParamByName('i').Value:=Form1.sp2.FieldByName('INNU').AsString;
      Form1.pFIBQuery2.ExecQuery;
      Form1.pFIBQuery2.Transaction.Commit;
      Application.ProcessMessages;
   end;
в Form1.sEdit10.Text - номер последней записи. Условие
Код:
where OGRN=:ogrnum and ID > '
говорит о том, что нужно выполнить обновление всех записей после последней добавленой.
Раньше, подобный код работал на MS Access + Delphi. Сейчас перенес его в Firebird и не могу заставить работать. Код выше дает один из двух результатов:
1. Если я пишу так:
Код:
...
    Form1.sp2.Open;
    Form1.pFIBDataSet4.Next;
...
то обновляется только первая запись.
2. Если пишу так:
Код:
...
    Form1.pFIBQuery2.ExecQuery;
    Form1.pFIBQuery2.Transaction.Commit;
    Application.ProcessMessages;
    Form1.pFIBDataSet4.Next;
 end;
...
то не обновляется ничего. Если надо, то могу выложить такой же код для MS Access. Прошу помощи в данной вопросе. Заранее спасибо за дельные советы.
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 29.11.2011, 16:34   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

1. Что-то хранимую процедуру не очень заметно
2. Вытащили из jurnal максимум ID, а потом пытаетесь обновить записи у котрых это ID больше максимального, естественно таких записей там нет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 29.11.2011, 16:42   #3
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Код:
1. Что-то хранимую процедуру не очень заметно
А ее и не надо смотреть. Она прекрасно работает. Ее даже я не видел, т.к. ее делал на сервере другой программист.
Код:
2. Вытащили из jurnal максимум ID, а потом пытаетесь обновить записи у котрых это ID больше максимального, естественно таких записей там нет
Не понял...Можно на примере пояснить? Голова уже не варит..
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 29.11.2011, 16:46   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
Form1.sp2.Close;
    Form1.sp2.Parameters.ParamByName('OGRN').Value:=Form1.pFIBDataSet4.FieldByName('OGRN').AsString;
    Form1.sp2.Open;
Видимо здесь отрабатывает ХП. Она что делает - добавляет новые записи в jurnal с ID большими OGRN?

ADD

Код:
//===============получение последней записи==================
  Form1.pFIBDataSet4.Close;
  Form1.pFIBDataSet4.SQLs.SelectSQL.Text:='select max(ID) as F from jurnal';
  Form1.pFIBDataSet4.Open;
  Form1.sEdit10.Text:=IntToStr(Form1.pFIBDataSet4.FieldByName('F').AsInteger); //получили MAX(ID)


//==============ОБНОВЛЕНИЕ ЧЕРЕЗ ХРАНИМУЮ ПРОЦЕДУРУ=======
   Form1.pFIBDataSet4.Close;
   Form1.pFIBDataSet4.Close;
   Form1.pFIBDataSet4.SQLs.SelectSQL.Text:='select OGRN from jurnal where ID > ' + Form1.sEdit10.Text; //Запрос выдернуть все записи у которых ID>MAX(ID)
   Form1.pFIBDataSet4.Open; //получили 0 записей, потому что их там нет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 29.11.2011 в 16:55.
Аватар вне форума Ответить с цитированием
Старый 29.11.2011, 17:58   #5
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Цитата:
Она что делает - добавляет новые записи в jurnal с ID большими OGRN?
Она просто вытаскивает кое какие данный из другой СУБД.

Я почему повяз на max(ID)-то..мне не нужно в цикле обновлять все записи, это замедлит работу программы. Мне нужно обновить только последние добавленные записи. Вот, код, который прекрасно работал в связке MS Access + Delphi. Может так проще понять будет что мне нужно)
Код:
  try
   Form1.qry1.Close;
   Form1.qry1.SQL.Clear;
   Form1.qry1.SQL.Text:='select CODENALOG,REGNUMBER,ARMIS,ARMDSV,RSV,RSVNOL,DATAPST,DATAOBR,TIMEOBR,DATASNYT,KATEGORIA,OGRN,INN,FIOOLD,FIONEW,ST,DATAZAYV,
NUMBER,ANSWER,PATHZAPROS,NAMEZAPROS,PERIOD_SZV6 from jurnal where DATASNYT=" " and ID >' + IntToStr(max);
   Form1.qry1.Open;
   Form1.qry1.First;
   Application.ProcessMessages;
   while not Form1.qry1.Eof do
   begin
      Form1.sp1.Close;
      Form1.sp1.ProcedureName:='PRG.FROM_STRAH';
      Form1.sp1.Parameters.ParamByName('OGRN').Value:=Form1.qry1.FieldByName('OGRN').AsString;
      Form1.sp1.Open;
      Application.ProcessMessages;

      Form1.qry1.Next;
      Form1.qry2.SQL.Clear;
      Form1.qry2.SQL.Text:='update jurnal set REGNUMBER=:num,DATASNYT=:ds,DATAPST=:dp,KATEGORIA=:k,FIONEW=:fn,ST=:s,INN=:i'+
' where OGRN=:ogrnum and DATASNYT=" " and ID >' + IntToStr(max);
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('num').Value:=Form1.sp1.FieldByName('REGNUMBERU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('ds').Value:=Form1.sp1.FieldByName('DATASNYTU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('dp').Value:=Form1.sp1.FieldByName('DATAPSTU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('k').Value:=Form1.sp1.FieldByName('KATEGORIA').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('fn').Value:=Form1.sp1.FieldByName('FIONEWU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('s').Value:=Form1.sp1.FieldByName('STU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('ogrnum').Value:=Form1.sp1.FieldByName('OGRNU').AsString;
      Application.ProcessMessages;
      Form1.qry2.Parameters.ParamByName('i').Value:=Form1.sp1.FieldByName('INNU').AsString;
      Application.ProcessMessages;
      Form1.qry2.ExecSQL;
      Application.ProcessMessages;
   end;
      Form1.qry2.SQL.Clear;
      Form1.qry2.SQL.Add('update jurnal set REGNUMBER="не зарегистрирован"');
      Form1.qry2.SQL.Add('where REGNUMBER=" " and DATASNYT=" " and ID >' + IntToStr(max));
      Form1.qry2.ExecSQL;
      Application.ProcessMessages;
  except on Exception do
  begin
  end;
  end;
Как говорится "Найдите 10 отличий"...
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.

Последний раз редактировалось mihali4; 29.11.2011 в 18:47.
artemavd вне форума Ответить с цитированием
Старый 29.11.2011, 18:21   #6
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

В этом коде вы работаете с каким то max. Я так понял, что в какой то момент вы запоминаете MAX(id), далее идет вставка новых записей и потом работает приведенный кусок кода. Он и будет править последние вставленные записи, у которых id>max. А в первом коде вы сразу выдернули MAX(id) и не вставляя новых записей, пытаетесь обновить то, чего нет. И явное завершение транзакции (Commit) в том контексте мне не понятно. А где явное начало транзакции (Begin Transaction)? И если уж использовать такие вещи явно, то и Rollback в случае ошибки обращения к базе нужно предусматривать. Это по опыту работы на MS SQL, думаю и firebird не очень в этом смысле отличается
Цитата:
мне не нужно в цикле обновлять все записи, это замедлит работу программы.
Вычисляйте по-другому границу выборки (id)
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 29.11.2011 в 18:25.
Аватар вне форума Ответить с цитированием
Старый 29.11.2011, 18:58   #7
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Цитата:
Я так понял, что в какой то момент вы запоминаете MAX(id), далее идет вставка новых записей и потом работает приведенный кусок кода. Он и будет править последние вставленные записи, у которых id>max.
Да, именно так и должно быть.
Цитата:
А в первом коде вы сразу выдернули MAX(id) и не вставляя новых записей, пытаетесь обновить то, чего нет
Код вставки в цикле выполняется перед срабатыванием кода с max. Сначала вставляются записи, потом они должны обновиться.
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Старый 29.11.2011, 19:47   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Ну не вижу я в посте 1 где вы вставляете после того как запомнили максимальный ID. Запоминайте MAX(ID) перед вставкой
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 30.11.2011, 17:08   #9
artemavd
Старожил
 
Аватар для artemavd
 
Регистрация: 05.06.2008
Сообщений: 4,206
По умолчанию

Разобрался сегодня как должно было быть. Да, макс. айди надо было поставить перед кодом вставки новых записей. А код обновления должен выглядеть так:
Код:
   Form1.pFIBDataSet4.Close;
   Form1.pFIBDataSet4.SQLs.SelectSQL.Text:='select OGRN from jurnal where ID > ' + Form1.sEdit10.Text;
   Form1.pFIBDataSet4.Open;
   Form1.pFIBDataSet4.First;
   Application.ProcessMessages;
   while not Form1.pFIBDataSet4.Eof do
   begin
    Form1.sp2.Close;
    Form1.sp2.Parameters.ParamByName('OGRN').Value:=Form1.pFIBDataSet4.FieldByName('OGRN').AsString;
    Form1.sp2.Open;
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Clear;
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add('update jurnal set REGNUMBER=:num,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' DATASNYT=:ds,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' DATAPST=:dp,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' KATEGORIA=:k,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' FIONEW=:fn,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' ST=:s,');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' INN=:i');
      Application.ProcessMessages;
      Form1.pFIBQuery2.SQL.Add(' where OGRN=:ogrnum and ID > ' + Form1.sEdit10.Text);
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('num').Value:=Form1.sp2.FieldByName('REGNUMBERU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('ds').Value:=Form1.sp2.FieldByName('DATASNYTU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('dp').Value:=Form1.sp2.FieldByName('DATAPSTU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('k').Value:=Form1.sp2.FieldByName('KATEGORIA').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('fn').Value:=Form1.sp2.FieldByName('FIONEWU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('s').Value:=Form1.sp2.FieldByName('STU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('ogrnum').Value:=Form1.pFIBDataSet4.FieldByName('OGRN').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ParamByName('i').Value:=Form1.sp2.FieldByName('INNU').AsString;
      Application.ProcessMessages;
      Form1.pFIBQuery2.ExecQuery;
      Application.ProcessMessages;
    Form1.pFIBDataSet4.Next;
   end;
выделенное красным должно стоять тут. Просто почему не работало? Потому что надо было у компонента pFIBDataSet4 выставить свойства poRefreshAfterPost, poStartTransaction, poDontCloseAfterEndTransaction в True. Не работало именно из-за последнего свойства. Поставил в True и все заработало как надо. Может кому пригодится решение данного вопроса.
Не стоит смеяться над человеком делающим шаг назад, возможно он делает разбег.
artemavd вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Цикл не работает Faridik Общие вопросы по Java, Java SE, Kotlin 1 14.08.2011 12:14
скрит работает в interbase а в FireBird выдает ошибку NikK1 БД в Delphi 9 13.04.2010 18:07
Не работает цикл Lisёноk Помощь студентам 5 23.03.2010 21:39
Цикл не работает doniyor Общие вопросы Delphi 1 06.12.2009 15:52
Цикл не работает...? Иринкаа Помощь студентам 6 17.11.2007 00:27