![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Transaction приводит в исключению [D7, XP]
delphinub © (2008-03-25 22:54:00)Сразу дабы не быть голословным привожу кусок кода
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 ''. Да, сообщение пустое :) Просто исключение не понимаю почему.
sniknik (2008-03-26 21:35:00) [1]> заработало вот так:
на одну команду делать свою транзакцию бессмысленно, она и так в ней выполняется...
> CompName:= DataModule1.OpenQuery.Fields[1].AsString;
>
> ... UPDATE '+ CompName+' SET ...
куча таблиц с именами хранящимися в данных еще одной таблицы? просто чудо а не структура базы... чудо юдо...
но даже в таком виде просто непочатый край для оптимизации...
вместо того чтобы тянуть на клиента полностью данные "FROM modifies", и потом по одной посылать кучу команд, лучше вытащить только имена таблиц (CompName), а абдейт строить групповой для всех записей одной таблици (с объединением), время обработки сократится на порядки. или тоже самое делать в процедуре (транзакцию поверх всех изменений делать. типа раз выполнилось то для всех таблиц, нет значит ни для одной).
а еще лучше структуру пересмотреть. (так чтобы вообще на все потребовался всего лиш 1 (один) запрос. хотя это и неинтересно наверное будет. транзакцию некуда присобачить... но она в общем то и в том виде, что сейчас бессмысленна)
Anatoly Podgoretsky (2008-03-26 21:12:00) [2]> delphinub (26.03.2008 15:18:13) [13]
Уже не смущает, просто имена похожие и мне показалось что это один и тот же компонент. Про dbexpress ничего не скажу, просто это неудачная на мой взгляд технологие, хотели как БДЕ и получилось как БДЕ
delphinub (2008-03-26 18:37:00) [3]покопавшись еще часик внедрил таки решение во весь остальной код и отладил. Всё работает. Спасибо всем, в особенности Johnmen!
delphinub (2008-03-26 17:36:00) [4]Добавил еще одно соединение с 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
Johnmen (2008-03-26 16:57:00) [5]
> "Почему добавление transaction приводит к ошибке выполнения
> запроса"
Дело в том, что библиотека dbExpress устроена в отношении коннектов так же, как и клиентская библ. MySQL - один коннект на один запрос, возвращающий данные; для запроса, не возвращающего данные, но выполняющегося в рамках существующего коннекта, коннект клонируется со всеми вытекающими типа поддержание транзакций и т.д. Т.е. нужна ещё одна транзакция в ещё одном коннекте.
Короче, если хочешь ещё попариться, поэкспериментируй с явной организацией коннектов и обеспечением каждому своей транзакции...
Если хочешь делать по-людски - используй АДО.
Плохиш (2008-03-26 16:50:00) [6]Думается, что, для начала, надо поставить обновления на делфи.
delphinub (2008-03-26 16:48:00) [7]"Почему добавление transaction приводит к ошибке выполнения запроса"
Johnmen (2008-03-26 16:46:00) [8]
> delphinub
Правильно ли я понимаю, что всё сводится к простому вопросу - почему не выполняется запрос [31]? Т.е. почему ошибка выполнения?
Плохиш (2008-03-26 16:45:00) [9]
> delphinub (26.03.08 16:42) [34]
> 2. а вот это фатально. как правильно?
Вариант 1 - использовать параметры.
Вариант 2 - QuotedStr.
delphinub (2008-03-26 16:42:00) [10]Плохиш
1. согласен, но убиватьза это не стал бы точно
2. а вот это фатально. как правильно?
delphinub (2008-03-26 16:39:00) [11]дело всё в том, что это мое первое приложение на Delphi и в наличие книга Хомоненко по D7, где очень подробно расписано про BDE & DBExpress, а технология ADO упоминается вскользь
Плохиш (2008-03-26 16:37:00) [12]
> delphinub (26.03.08 16:29) [27]
> Плохиш вы так всех перестреляете. К тому же если вы хотите
> показать свое превосходство можно было бы написать еще на
> что лучше исправить указаные строчки.
1. Свойство SQL типа TStrings имеет в свою очередь свойство Text.
2. Попробуй обновить запись с полем name имеющим значение Д'Артаньян.
> В противном случае вы не вызываете ничего кроме раздражения.
Я аж прослезился...
delphinub (2008-03-26 16:37:00) [13]UPDATE comp1 SET quantity=quantity-3 WHERE name='CD4001BM96'
Johnmen (2008-03-26 16:35:00) [14]
> Плохиш © (26.03.08 16:32) [29]
Честно говоря, я даже таких не вижу...:)
Плохиш (2008-03-26 16:32:00) [15]
> Да все поднапрягли изрядно изношенные телепаторы и получили
> MSSQL
Хм, использовать в D7 dbExpress вместо родного АДО для доступа к MSSQL вижу только две причины, это написание кроссплатформенных приложений или быть извращенцем. Что-то первого варианта здесь не наблюдается ;-)
Johnmen (2008-03-26 16:30:00) [16]
> delphinub (26.03.08 16:26) [25]
Выведи куда-либо и приведи здесь реальную строку запроса в DataModule1.QueryComp.
delphinub (2008-03-26 16:29:00) [17]Плохиш вы так всех перестреляете. К тому же если вы хотите показать свое превосходство можно было бы написать еще на что лучше исправить указаные строчки. В противном случае вы не вызываете ничего кроме раздражения.
3. MS SQL 2000
Johnmen (2008-03-26 16:27:00) [18]
> Плохиш © (26.03.08 16:22) [24]
> 3. Это один я заметил, что используемая бд не указана?
Да все поднапрягли изрядно изношенные телепаторы и получили MSSQL
:))
delphinub (2008-03-26 16:26:00) [19]добавляю потому что после внесений изменений эти таблицы они еще должны сохраниться в Excel. А там может произойти нечто непредвиденное, например пользователь нажмет "отмена" во время диалога SaveAs =) Тогда надо делать Rollback.
Про исключение и строку я все написал уже несколько раз. Повторюсь:
DataModule1.QueryComp.ExecSQL();- строка
Исключение EDatabaseError с пустым Message
Плохиш (2008-03-26 16:22:00) [20]Значится так:
1. Убил бы за это
> DataModule1.OpenQuery.SQL.Clear;
> DataModule1.OpenQuery.SQL.Add(
2. Убил бы за это
> name='''+Value+'''');
3. Это один я заметил, что используемая бд не указана?
4. Необходимо поинтересоваться, а совместим ли используемый dbExpress драйвер с используемой версией бд...