Текущий архив: 2008.04.20;
Скачать: CL | DM;
Вниз
Transaction приводит в исключению Найти похожие ветки
← →
delphinub (2008-03-25 22:54) [0]Сразу дабы не быть голословным привожу кусок кода
procedure TExcel.Change(FileName: String);
var i: integer;
begin
DataModule1.OpenQuery.SQL.Clear;
DataModule1.OpenQuery.SQL.Add("SELECT * FROM modifies");
DataModule1.OpenQuery.Open;
//DataModule1.MSSQLConnection.StartTransaction(TransDesc);
for i:=0 to DataModule1.OpenQuery.RecordCount-1 do
begin
CompName := DataModule1.OpenQuery.Fields[1].AsString;
Value := DataModule1.OpenQuery.Fields[0].AsString;
qua := DataModule1.OpenQuery.Fields[2].AsInteger;
DataModule1.QueryComp.SQL.Clear;
DataModule1.QueryComp.SQL.Add("UPDATE "+CompName+" SET quantity=quantity-"+IntToStr(qua)+" WHERE name="""+Value+"""");
DataModule1.QueryComp.ExecSQL();
DataModule1.OpenQuery.Next;
end;
//DataModule1.MSSQLConnection.Commit(TransDesc);
exc.SaveFile(FileName);
DataModule1.OpenQuery.Close;
end;
раскомментирование управления транкзацией приводит к ошибке в выделенной строке с текстом EDatabaseError with Message "". Да, сообщение пустое :) Просто исключение не понимаю почему.
← →
delphinub (2008-03-25 22:55) [1]кстати, если в таблице modifies была всего одна строчка, то почему-то всё срабатывает без ошибок..
← →
Loginov Dmitry © (2008-03-26 00:33) [2]1) Возможно, транзакцию требуется стартануть до OpenQuery.Open, либо же что-то где-то настроено неверно.
2) Для перебора записей цикл if не используют. Правильно так:DataModule1.OpenQuery.First;
while not DataModule1.OpenQuery.Eof do
begin
// Обработка очередной записи
DataModule1.OpenQuery.Next;
end;
3) Защити работу с набором данных DataModule1.OpenQuery с помощью оператора try..finally:DataModule1.OpenQuery.Open;
try
//
finally
DataModule1.OpenQuery.Close;
end;
Иначе при возникающих в функции ошибках она становится "одноразовой", т.к. после первого вызова дело до Close не доходит, а при втором вызове ошибка произойдет на SQL.Clear, а это только усложняет отладку.
← →
Loginov Dmitry © (2008-03-26 00:34) [3]> цикл if
for, разумеется
← →
delphinub (2008-03-26 01:18) [4]1) Стартую до. Ничего не изменилось
2) Изменил цикл на while. Ошибка стала вываливаться в главный юнит туда, от куда вызывается функция change.
3) Защитил но это не от сюда:
Грамотно пользоваться отлпадчиками я не умею, однако при помощи пресловутой i и инкремента я выяснил, что ошибка возникает при _первой_ итерации цикла while на строчкеDataModule1.QueryComp.ExecSQL();
напоминаю, что в случае, когда итерация _всего одна_ и второй не предполагается, то ошибки нет. Также её нет если убрать transaction. Изменения в таком случае в таблицу заносятся, то есть подготовленные переменные и запрос не содержат ошибок. Тут какая-то принципиальная особенность я так думаю.. тонкость..
← →
Anatoly Podgoretsky © (2008-03-26 01:54) [5]Где новый код?
← →
delphinub (2008-03-26 02:12) [6]
procedure TExcel.Change(FileName: String);
var i: integer;
begin
DataModule1.OpenQuery.SQL.Clear;
DataModule1.OpenQuery.SQL.Add("SELECT * FROM modifies");
DataModule1.MSSQLConnection.StartTransaction(TransDesc);
DataModule1.OpenQuery.Open;
while not DataModule1.OpenQuery.Eof do
begin
CompName := DataModule1.OpenQuery.Fields[1].AsString;
Value := DataModule1.OpenQuery.Fields[0].AsString;
qua := DataModule1.OpenQuery.Fields[2].AsInteger;
DataModule1.QueryComp.SQL.Clear;
DataModule1.QueryComp.SQL.Add("UPDATE "+CompName+" SET quantity=quantity-"+IntToStr(qua)+" WHERE name="""+Value+"""");
DataModule1.QueryComp.ExecSQL();
DataModule1.OpenQuery.Next;
end;
DataModule1.MSSQLConnection.Commit(TransDesc);
DataModule1.OpenQuery.Close;
end;
жирным выделил не срабатывающую в первой итерации команду
← →
Loginov Dmitry © (2008-03-26 08:02) [7]> Защитил но это не от сюда
что значит "но это не от сюда"? Защищать нужно всегда, иначе правильного и надежного приложения никогда не сделаешь.
А в твоем случае еще и для транзакции TRY..FINALLY нужен:DataModule1.MSSQLConnection.StartTransaction(TransDesc);
try
// ..................
DataModule1.MSSQLConnection.Commit(TransDesc);
finally
if DataModule1.MSSQLConnection.InTransaction then
DataModule1.MSSQLConnection.RollBack;
end;
приблизительно так
← →
ЮЮ © (2008-03-26 08:37) [8]Если это MS SQL, почему не написать 1 запрос на UDATE вместо этого "программирования"?
← →
delphinub (2008-03-26 14:43) [9]Loginov, Dmitry: я владею конструкциями try-expect и try-finally и активно их использую, просто в данном случае это не приводит к каким-либо положительным последствиям, всё равно возникает исключение и транкзация откатывается назад. А по сути и откатывать нечего, так как изменения еще не вносились.
ЮЮ: наверное это от того, что я не знаю такого простого способа.
Тем не менее вопрос остается открытым...
← →
Anatoly Podgoretsky © (2008-03-26 14:59) [10]Смущает меня это "DataModule1.QueryComp.SQL." в одной транзакции, ты чего экономишь на спичках
← →
Anatoly Podgoretsky © (2008-03-26 15:02) [11]У тебя что за компоненты, не АДО ли случайно, тогда послушай sniknik, что он говорит по поводу использования TAdoQuery - очень наглядный пример к его утверждению.
Прокляну Борланда за подобную подлость по отношению к подрастающему поколению, постарались не хуже Архангельского.
← →
Johnmen © (2008-03-26 15:12) [12]Это точно не АДО. Нет там таких методов у объектов.
>delphinub
А что?
← →
delphinub (2008-03-26 15:18) [13]Нет, я использую DBExpress с его компонентами. Я немного не понял что смущает.. Как еще можно реализовать подобное обновление таблицы?
← →
Johnmen © (2008-03-26 15:22) [14]
StartTransaction;
try
...
Commit;
except
RollBack;
end;
← →
ANB (2008-03-26 15:24) [15]
> delphinub (26.03.08 15:18) [13]
Я правильно понял, что в первой таблице (по которой идет цикл) хранятся имена таблиц, которые надо обновлять ?
← →
delphinub (2008-03-26 15:24) [16]так в вышенаписаном коде суть так же
← →
delphinub (2008-03-26 15:25) [17]ANB да правильно поняли!
← →
Johnmen © (2008-03-26 15:34) [18]
> так в вышенаписаном коде суть так же
не так же.
← →
delphinub (2008-03-26 15:49) [19]
procedure TExcel.Change(FileName: String);
var i: integer;
begin
DataModule1.OpenQuery.SQL.Clear;
DataModule1.OpenQuery.SQL.Add("SELECT * FROM modifies");
DataModule1.MSSQLConnection.StartTransaction(TransDescr);
try
DataModule1.OpenQuery.Open;
while not DataModule1.OpenQuery.Eof do
begin
CompName := DataModule1.OpenQuery.Fields[1].AsString;
Value := DataModule1.OpenQuery.Fields[0].AsString;
qua := DataModule1.OpenQuery.Fields[2].AsInteger;
DataModule1.QueryComp.SQL.Clear;
DataModule1.QueryComp.SQL.Add("UPDATE "+CompName+" SET quantity=quantity-"+IntToStr(qua)+" WHERE name="""+Value+"""");
DataModule1.QueryComp.ExecSQL();
DataModule1.OpenQuery.Next;
end;
DataModule1.MSSQLConnection.Commit(TransDescr);
except
DataModule1.MSSQLConnection.Rollback(TransDescr);
ShowMessage("Данные не изменены!");
end;
DataModule1.OpenQuery.Close;
end;
Окей ввел сюда try-except. До этого они стояли при вызове функции. Ниче не меняется.
← →
Johnmen © (2008-03-26 15:53) [20]
> Ниче не меняется.
А что наблюдается?
← →
delphinub (2008-03-26 16:01) [21]наблюдается такое же исключение после которого если нажать F9 появляется табличка Данные не изменены!...
← →
delphinub (2008-03-26 16:02) [22]повторю что без этих строчек про transaction всё работает на раз. Изменения вносятся при любом количестве записей в таблице modifies. Проверял через Enterprise Manager
← →
Johnmen © (2008-03-26 16:21) [23]
> наблюдается такое же исключение после которого если нажать
> F9 появляется табличка Данные не изменены!...
Давай так, тебе задают КОНКРЕТНЫЕ уточняющие вопросы, ты на них КОНКРЕТНО отвечаешь.
Какое именно исключение наблюдается?
На какой строке кода?
ЗЫ
повторю что без этих строчек про transaction всё работает на раз.
Зачем тогда ты написал эти строчки про transaction?
← →
Плохиш © (2008-03-26 16:22) [24]Значится так:
1. Убил бы за это
> DataModule1.OpenQuery.SQL.Clear;
> DataModule1.OpenQuery.SQL.Add(
2. Убил бы за это
> name="""+Value+"""");
3. Это один я заметил, что используемая бд не указана?
4. Необходимо поинтересоваться, а совместим ли используемый dbExpress драйвер с используемой версией бд...
← →
delphinub (2008-03-26 16:26) [25]добавляю потому что после внесений изменений эти таблицы они еще должны сохраниться в Excel. А там может произойти нечто непредвиденное, например пользователь нажмет "отмена" во время диалога SaveAs =) Тогда надо делать Rollback.
Про исключение и строку я все написал уже несколько раз. Повторюсь:DataModule1.QueryComp.ExecSQL();
- строка
Исключение EDatabaseError с пустым Message
← →
Johnmen © (2008-03-26 16:27) [26]
> Плохиш © (26.03.08 16:22) [24]
> 3. Это один я заметил, что используемая бд не указана?
Да все поднапрягли изрядно изношенные телепаторы и получили MSSQL
:))
← →
delphinub (2008-03-26 16:29) [27]Плохиш вы так всех перестреляете. К тому же если вы хотите показать свое превосходство можно было бы написать еще на что лучше исправить указаные строчки. В противном случае вы не вызываете ничего кроме раздражения.
3. MS SQL 2000
← →
Johnmen © (2008-03-26 16:30) [28]
> delphinub (26.03.08 16:26) [25]
Выведи куда-либо и приведи здесь реальную строку запроса в DataModule1.QueryComp.
← →
Плохиш © (2008-03-26 16:32) [29]
> Да все поднапрягли изрядно изношенные телепаторы и получили
> MSSQL
Хм, использовать в D7 dbExpress вместо родного АДО для доступа к MSSQL вижу только две причины, это написание кроссплатформенных приложений или быть извращенцем. Что-то первого варианта здесь не наблюдается ;-)
← →
Johnmen © (2008-03-26 16:35) [30]
> Плохиш © (26.03.08 16:32) [29]
Честно говоря, я даже таких не вижу...:)
← →
delphinub (2008-03-26 16:37) [31]UPDATE comp1 SET quantity=quantity-3 WHERE name="CD4001BM96"
← →
Плохиш © (2008-03-26 16:37) [32]
> delphinub (26.03.08 16:29) [27]
> Плохиш вы так всех перестреляете. К тому же если вы хотите
> показать свое превосходство можно было бы написать еще на
> что лучше исправить указаные строчки.
1. Свойство SQL типа TStrings имеет в свою очередь свойство Text.
2. Попробуй обновить запись с полем name имеющим значение Д"Артаньян.
> В противном случае вы не вызываете ничего кроме раздражения.
Я аж прослезился...
← →
delphinub (2008-03-26 16:39) [33]дело всё в том, что это мое первое приложение на Delphi и в наличие книга Хомоненко по D7, где очень подробно расписано про BDE & DBExpress, а технология ADO упоминается вскользь
← →
delphinub (2008-03-26 16:42) [34]Плохиш
1. согласен, но убиватьза это не стал бы точно
2. а вот это фатально. как правильно?
← →
Плохиш © (2008-03-26 16:45) [35]
> delphinub (26.03.08 16:42) [34]
> 2. а вот это фатально. как правильно?
Вариант 1 - использовать параметры.
Вариант 2 - QuotedStr.
← →
Johnmen © (2008-03-26 16:46) [36]
> delphinub
Правильно ли я понимаю, что всё сводится к простому вопросу - почему не выполняется запрос [31]? Т.е. почему ошибка выполнения?
← →
delphinub (2008-03-26 16:48) [37]"Почему добавление transaction приводит к ошибке выполнения запроса"
← →
Плохиш © (2008-03-26 16:50) [38]Думается, что, для начала, надо поставить обновления на делфи.
← →
Johnmen © (2008-03-26 16:57) [39]
> "Почему добавление transaction приводит к ошибке выполнения
> запроса"
Дело в том, что библиотека dbExpress устроена в отношении коннектов так же, как и клиентская библ. MySQL - один коннект на один запрос, возвращающий данные; для запроса, не возвращающего данные, но выполняющегося в рамках существующего коннекта, коннект клонируется со всеми вытекающими типа поддержание транзакций и т.д. Т.е. нужна ещё одна транзакция в ещё одном коннекте.
Короче, если хочешь ещё попариться, поэкспериментируй с явной организацией коннектов и обеспечением каждому своей транзакции...
Если хочешь делать по-людски - используй АДО.
← →
delphinub (2008-03-26 17:36) [40]Добавил еще одно соединение с MS SQL.. заработало вот так:
procedure TExcel.Change(FileName: String);
var i: integer;
begin
DataModule1.OpenQuery.SQL.Clear;
DataModule1.OpenQuery.SQL.Add("SELECT * FROM modifies");
DataModule1.SQLClon.Params.Assign(DataModule1.MSSQLConnection.Params);
DataModule1.SQLClon.Connected:=true;
DataModule1.MSSQLConnection.StartTransaction(TransDescr);
try
DataModule1.OpenQuery.Open;
while not DataModule1.OpenQuery.Eof do
begin
CompName := DataModule1.OpenQuery.Fields[1].AsString;
Value := DataModule1.OpenQuery.Fields[0].AsString;
qua := DataModule1.OpenQuery.Fields[2].AsInteger;
DataModule1.SQLClon.StartTransaction(TD);
DataModule1.Clon.SQL.Clear;
//MainForm.Label1.Caption:="UPDATE "+CompName+" SET quantity=quantity-"+IntToStr(qua)+" WHERE name="""+Value+"""";
DataModule1.Clon.SQL.Add("UPDATE "+CompName+" SET quantity=quantity-"+IntToStr(qua)+" WHERE name="""+Value+"""");
DataModule1.Clon.ExecSQL();
DataModule1.SQLClon.Commit(TD);
DataModule1.OpenQuery.Next;
end;
DataModule1.MSSQLConnection.Commit(TransDescr);
except
ShowMessage("ÊÓ!");
DataModule1.MSSQLConnection.Rollback(TransDescr);
end;
// exc.SaveFile(FileName);
DataModule1.OpenQuery.Close;
end;
озонал необходимость перехода на ADO
Страницы: 1 2 вся ветка
Текущий архив: 2008.04.20;
Скачать: CL | DM;
Память: 0.57 MB
Время: 0.018 c