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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 23.06.2010, 16:22   #1
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию Дублирование записей при Update

При выполнении запроса Update записи в БД дублируются. Причем не каждый раз, а как звезды на небе станут. может и продублировать, а может и нет.
Код:
id:=Button11.Tag;
dogovor:=ed_ed_Dogovor.Text;
Card:=ed_ed_Card.Text;
fio:=ed_ed_Fio.Text;
adrr:=ed_ed_Adress.Text;
tel:=ed_ed_Tel.Text;
regdate:=ed_ed_RegData.Date;
hisdatefrom:=ed_ed_HisPayfrom.Date;
hisdateto:=ed_ed_HisPayto.Date;
ourdateto:=ed_ed_OurPayto.Date;
sql:=format('UPDATE clients SET dogovor=''%s'',card=''%s'',fio=''%s'',pakid=''%d'',regdata=''%s'',adr=''%s'',fon=''%s'',firmid=''%d'',hispaydatafrom=''%s'',hispaydatato=''%s'',ourpaydatato=''%s'' WHERE id=''%d'';',
[dogovor,card,fio,pakid,datetostr(regdate),adrr,tel,firmid,datetostr(hisdatefrom),datetostr(hisdateto),datetostr(ourdateto),id]);
if fmMain.db_SQL(sql,false) then
 begin
   ShowMessage('Редактирование клиента');
   sql:=format('INSERT INTO history (clid,date,value) VALUE(''%d'',''%s'',''%s'');',[id,datetostr(now),'Редактирование клиента']);
   if (fmMain.db_SQL(sql,false))<>true then ShowError('Невозможно обновить историю','Ошибка запроса к базе');
   ini.WriteInteger('db','clientid',id);
 end
else
 ShowError('Невозможно редактировать клиента','Ошибка запроса к базе');
end;
Error_kpi вне форума Ответить с цитированием
Старый 23.06.2010, 16:41   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Ну а кто знает что делает fmMain.db_SQL?
И кстати, с чего ты взял что этот код выполняется не дважды?
Как и где ты его вызываешь?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.06.2010, 17:04   #3
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию

Вызываю по нажатию на кнопке, это раз
Код:
function TfmMain.db_SQL(sql:String;resp:boolean):boolean;
begin
  result:=false;
  if not zc1.Connected then
   fmMain.db_reconnect;
  if not zc1.Connected then
   begin
    ShowError('Запит не виконано','Немає підключення до бази данних');
    exit;
   end;
  zq1.SQL.Clear;
  zq1.SQL.Text:='';
  zq1.SQL.Text:=sql;
  try
    if resp then
      begin
       zq1.Close;
       zq1.Open;
       result:=true;
      end
    else
      begin
        zq1.Close;
        zq1.ExecSQL;
        zq1.Close;
        result:=true;
      end;
   except
   on E:Exception do
       ShowError('Помилка виконання запиту',E.Message);
   end;
end;
Ну а если и два раза выполнить то чо? Дублироваться запись не должна всеравно это-же UPDATE, а не INSERT...
Error_kpi вне форума Ответить с цитированием
Старый 23.06.2010, 18:29   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
При выполнении запроса Update записи в БД дублируются
погодите..
т.е. вы хотите сказать, что после
Update clients set ... where id = ВашID
в таблице clients появляются ДВЕ записи с одним ID ?!!

но это же невозможно!
Что за СУБД, через что подключаетесь?
В дублировании удостоверялись 100% ?! (могут неверные запросы (неверно связанные из нескольких таблиц) показывать мнимое дублирование, которого, разумеется, в таблице нет!
Serge_Bliznykov вне форума Ответить с цитированием
Старый 23.06.2010, 18:38   #5
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию

Цитата:
В дублировании удостоверялись 100% ?!
да вызваполнив запрос SELECT * FROM clients WHERE id=МойID.
Цитата:
в таблице clients появляются ДВЕ записи с одним ID ?!!
ДА, а то и 4 записи
Цитата:
Что за СУБД, через что подключаетесь?
MySQL 5.1, ZeoS lib
Цитата:
но это же невозможно!
сам понимаю но.... дефакто глюк есть.

Глюк проявился только на этапе эксплуатации. На тестовой базе все досихпор работает как часы, а вот в рабочей базе нет. Причем глюк странный появляется рандомно. Но при добавлении одной и тойже записи (абсолютно тойже, кроме ид) и ее редактировании появляется обязательно.

Может связанно с самими данными, хотя редактировалась дата....
Error_kpi вне форума Ответить с цитированием
Старый 23.06.2010, 18:42   #6
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию

Вот структура базы на всякий случай
clients
+----------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | YES | | NULL | |
| dogovor | varchar(20) | YES | | NULL | |
| card | varchar(20) | YES | | NULL | |
| fio | varchar(50) | YES | | NULL | |
| pakid | int(10) unsigned | YES | | NULL | |
| regdata | date | YES | | NULL | |
| adr | varchar(50) | YES | | NULL | |
| fon | varchar(50) | YES | | NULL | |
| firmid | int(10) unsigned | YES | | NULL | |
| hispaydatafrom | date | YES | | NULL | |
| hispaydatato | date | YES | | NULL | |
| ourpaydatato | date | YES | | NULL | |
| ourpaydatafrom | date | YES | | NULL | |
| coment | varchar(255) | YES | | NULL | |
+----------------+------------------+------+-----+---------+-------+

pakets

+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | YES | | NULL | |
| name | varchar(60) | YES | | NULL | |
| price | float | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+

firm

+-------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id | int(10) unsigned | YES | | NULL | |
| name | varchar(20) | YES | | NULL | |
| adrr | varchar(40) | YES | | NULL | |
| phone | varchar(20) | YES | | NULL | |
+-------+------------------+------+-----+---------+-------+

history
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| clid | int(11) | YES | | NULL | |
| date | date | YES | | NULL | |
| value | varchar(200) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
Error_kpi вне форума Ответить с цитированием
Старый 23.06.2010, 18:49   #7
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию

Код:
procedure TfmMain.Button11Click(Sender: TObject);
var
 firmid,pakid,id:cardinal;
 dogovor,card,fio,adrr,tel,sql:String;
 regdate,ourdatefrom,ourdateto,hisdatefrom,hisdateto:TDate;
 function datetostr(const AD:TDate):String;
  var
   y,d,m:word;
  begin
   decodedate(AD,y,m,d);
   result:=inttostr(y)+'-'+inttostr(m)+'-'+inttostr(d);
  end;
begin
if (ed_ed_Dogovor.Text='') or (ed_ed_Card.Text='') or (ed_ed_fio.Text='') or (cb_ed_Paket.Text='') then
 begin
  showmessage('Введены не полные данные');
  exit;
 end;

if fmMain.db_SQL(format('SELECT firm.id as firmid FROM firm WHERE firm.name=''%s'';',[cb_ed_firm.Text]),true) then
 begin
 firmid:=ZQ1.FieldByName('firmid').AsInteger;
 end
 else
  begin
    ShowError('Невозможно узнать id фирмы','Ошибка запроса к базе');
    exit;
  end;
if fmMain.db_SQL(format('SELECT pakets.id as pakid FROM pakets WHERE pakets.name=''%s'';',[cb_ed_Paket.Text]),true) then
 begin
 pakid:=ZQ1.FieldByName('pakid').AsInteger;
 end
 else
  begin
    ShowError('Невозможно узнать id пакета','Ошибка запроса к базе');
    exit;
  end;
id:=Button11.Tag;
dogovor:=ed_ed_Dogovor.Text;
Card:=ed_ed_Card.Text;
fio:=ed_ed_Fio.Text;
adrr:=ed_ed_Adress.Text;
tel:=ed_ed_Tel.Text;
regdate:=ed_ed_RegData.Date;
hisdatefrom:=ed_ed_HisPayfrom.Date;
hisdateto:=ed_ed_HisPayto.Date;
ourdateto:=ed_ed_OurPayto.Date;
sql:=format('UPDATE clients SET dogovor=''%s'',card=''%s'',fio=''%s'',pakid=''%d'',regdata=''%s'',adr=''%s'',fon=''%s'',firmid=''%d'',hispaydatafrom=''%s'',hispaydatato=''%s'',ourpaydatato=''%s'' WHERE id=''%d'';',
[dogovor,card,fio,pakid,datetostr(regdate),adrr,tel,firmid,datetostr(hisdatefrom),datetostr(hisdateto),datetostr(ourdateto),id]);
if fmMain.db_SQL(sql,false) then
 begin
   ShowMessage('Редактирование клиента');
   sql:=format('INSERT INTO history (clid,date,value) VALUE(''%d'',''%s'',''%s'');',[id,datetostr(now),'Редактирование клиента']);
   if (fmMain.db_SQL(sql,false))<>true then ShowError('Невозможно обновить историю','Ошибка запроса к базе');
   ini.WriteInteger('db','clientid',id);
 end
else
 ShowError('Невозможно редактировать клиента','Ошибка запроса к базе');
end;
Полный текст функции нажатия на кнопки.

Последний раз редактировалось Error_kpi; 23.06.2010 в 18:56.
Error_kpi вне форума Ответить с цитированием
Старый 23.06.2010, 21:10   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

абсолютно не могу ничего сказать. Ибо баг где-то глубоко.. я бы грешил на компоненты доступа..

сразу замечания.
1) проверьте на наличие триггеров! Они очень сильно могут подпортить Вам жизнь.

2) Если добавить запись. Закрыть приложение (и по возможности остановить сервер). Потом запустить.
Обязательно убедиться, что запись с нужным ID одна одинёшенька и потом мучить её Update - сначала ручками через выполнение запросов. А потом мучить Update через программу - удасться повторить дублирование?!

3) Почему у Вас ключевые поля NULL ?! Это как?!
Только Уникальные и NOT NULL
Это же основа любой реляционной БД
Serge_Bliznykov вне форума Ответить с цитированием
Старый 24.06.2010, 12:19   #9
soleil@mmc
SQL-коддинг
Участник клуба
 
Регистрация: 16.01.2009
Сообщений: 1,192
По умолчанию

да будет вам - компоненты доступа...
ТС нахватался по верхам кода и слепил нечто, что теперь доставляет кучу хлопот

структуру БД нужно разрабатывать независимо от кода проги и проверять работоспособность созданной структуры БД нужно прямыми вставками/апдейтами/удалениями в базу, а дальше навешивать для полноценной работы процедуры, открывающие некий функционал для работы с бд из прог

ну читать, читать, читать правильные книжки - начать с "нормальных форм"
soleil@mmc вне форума Ответить с цитированием
Старый 24.06.2010, 13:56   #10
Error_kpi
Пользователь
 
Регистрация: 23.06.2010
Сообщений: 17
По умолчанию

Из Command Line БД работает как часы.
В тестовом варианте базы тоже.
Цитата:
3) Почему у Вас ключевые поля NULL ?! Это как?!
Только Уникальные и NOT NULL
Это же основа любой реляционной БД
Естественно, потому они контролируются программно (во время создания базы не знал как выставляются атрибуты полей в MySQL, впервые с этой СУБД работаю).

Цитата:
2) Если добавить запись. Закрыть приложение (и по возможности остановить сервер). Потом запустить.
Обязательно убедиться, что запись с нужным ID одна одинёшенька и потом мучить её Update - сначала ручками через выполнение запросов. А потом мучить Update через программу - удасться повторить дублирование?!
Нет дублирование работает ТОЛЬКО из программы и ТОЛЬКО на рабочей базе. Программы и версия СУБД (а также настройки) идентичны.

Цитата:
ТС нахватался по верхам кода и слепил нечто, что теперь доставляет кучу хлопот
?....


Кто-то что по делу может посоветовать?

Последний раз редактировалось Error_kpi; 24.06.2010 в 14:01.
Error_kpi вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Дублирование при печати pavel.ignatenko Microsoft Office Excel 1 03.03.2010 23:39
Ошибка при редактировании поля (в Update) Droid БД в Delphi 4 12.07.2009 19:51
Автоматический Update при открытии файла ruavia3 Microsoft Office Excel 3 16.03.2009 11:31
Update - Обновление всех записей Veroonya SQL, базы данных 4 15.12.2008 13:42
update или исправление записей в таблицах. Roof БД в Delphi 4 15.08.2008 15:35