Rambler's Top100
"Knowledge itself is power"
F.Bacon
Поиск | Карта сайта | Помощь | О проекте | ТТХ  
 Круглый стол
  
Правила КС
>> Настройки

Фильтр вопросов
>> Новые вопросы
отслеживать по
>> Новые ответы

Избранное

Страница вопросов
Поиск по КС


Специальные проекты:
>> К л ю к в а
>> Г о л о в о л о м к и

Вопрос №

Задать вопрос
Off-topic вопросы

Помощь

 
 К н и г и
 
Книжная полка
 
 
Библиотека
 
  
  
 


Поиск
 
Поиск по КС
Поиск в статьях
Яndex© + Google©
Поиск книг

 
  
Тематический каталог
Все манускрипты

 
  
Карта VCL
ОШИБКИ
Сообщения системы

 
Форумы
 
Круглый стол
Новые вопросы

 
  
Базарная площадь
Городская площадь

 
   
С Л С

 
Летопись
 
Королевские Хроники
Рыцарский Зал
Глас народа!

 
  
ТТХ
Конкурсы
Королевская клюква

 
Разделы
 
Hello, World!
Лицей

Квинтана

 
  
Сокровищница
Подземелье Магов
Подводные камни
Свитки

 
  
Школа ОБЕРОНА

 
  
Арсенальная башня
Фолианты
Полигон

 
  
Книга Песка
Дальние земли

 
  
АРХИВЫ

 
 

Сейчас на сайте присутствуют:
 
  
 
Во Флориде и в Королевстве сейчас  15:32[Войти] | [Зарегистрироваться]
Ответ на вопрос № 46315

30-10-2006 07:24
Приветствую! Использую ADO примерно так:


Button1.onClick;
begin
ADOQuery1.Active := false;
ADOQuery1.SQL.Text :='....';
ADOQuery1.ExecSQL;
..
ADOQuery1.Active := false;
ADOQuery1.SQL.Text :='....';
ADOQuery1.ExecSQL;<----Допустим, здесь происходит ошибка

end;

Возможно ли отменить все предыдущие транзакции при условии, что произошла ошибка?

[+] Добавить в избранные вопросы

Отслеживать ответы на этот вопрос по RSS

Ответы:


Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице.
Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.

08-11-2006 15:06 | Комментарий к предыдущим ответам
Эх... Куда катимся!!! Раньше написать программу под 16Кб - это просто было расточительно... А сейчас? А сейчас с гигабайтами оперативки все пишут как вздумается... А потом производителям ПК говорим, что их мащностей маловато... Надо ещё пол терабайта оперативки, процессор P-V 5000 GHz и т.п. Сразу скажу: не уважаю тех, кто делает тяп-ляп... Восхищаюсь интузазистами, которые в 64 Кб 3D приложение умещают! Асм великое дело! Ладно... Видать я старею... Не буду бурчать...

P.S. Кстати... Много катался по командировкам по "окраинам" России. И там многие ещё используют такие компы, как я указал. А у меня конечно старенький, но P-IV 2400MHz с гигом оперативки...

08-11-2006 00:45
Возьми рудимент типа P-II 400 MHz/16 Mb RAM...

Так на нем же разве что Windows 95 запустится...
Пора уже тебе поменять операционку :)

07-11-2006 12:29
To Green:

Возьми рудимент типа P-II 400 MHz/16 Mb RAM и попробуй "подобавлять" хотя бы килобайт 16 ... Вот там и увидешь разницу... ;)


07-11-2006 00:16
2 Куфенко Павел:

Спасибо за науку, много нового узнал из твоих сообщений :)

Хочу только уточнить - "Запросы-то одинаковы а код и время их построения разные" - а вы пробовали измерить это время? Оно вообще поддается измерению?

06-11-2006 17:53
To TPID:

Да потому что нет BeginUpdate/EndUpdate! А это приводит к тому, что несколько операторов SQL.Add заставляют компонент парсить запрос на наличие параметров, которых может и не быть! А это, хоть и маленькое, но время процессора! И это только на маленьких запросах... :)))

To Banderas:

Хоть один человек понимает о чём я толькую... ;)))



06-11-2006 04:46 | Комментарий к предыдущим ответам
Запросы-то одинаковы а код и время их построения разные :) Павел прав.

06-11-2006 02:02 | Сообщение от автора вопроса
А теперь догадайся почему... ;)

А почему?

ADOQuery1.SQL.Clear;
ADOQuery2.SQL.Clear;
ADOQuery1.SQL.Add('SELECT * FROM Employees');
ADOQuery1.SQL.Add('WHERE EmpID = 1;');
ADOQuery2.SQL.Text :='SELECT * FROM Employees' + #13 + #10 +
      'WHERE EmpID = 1;' + #13 + #10;

if ADOQuery1.SQL.Text = ADOQuery2.SQL.Text then ShowMessage('Одинаковы');



Этот код говорит, что варианты одинаковы...

05-11-2006 16:58
To Green:

Не хорошо как-то получается... Из твоих обяснений в данном топике можно сделать вывод, что SQL.Text и несколько SQL.Add выполняют одно и тоже... Ты привёл здесь кусок кода из TADOQuery, но... Почему же ты убрал BeginUpdate/EndUpdate из кода? SQL.Add в SQL.Text совсем не так работает, как простой SQL.Add и ты это знаешь, славный рыцарь... Потому что без BeginUpdate/EndUpdate при каждом SQL.Add запросы снова парсятся!

// Этот вариант

ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('select * from employees');
ADOQuery1.SQL.Add('where empid = :empid');

// Не равен этому

ADOQuery1.SQL.Text := 'select * from employees where empid = :empid';

// Но равен этому

ADOQuery1.SQL.BeginUpdate;
try
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('select * from employees');
  ADOQuery1.SQL.Add('where empid = :empid');
finally
  ADOQuery1.SQL.EndUpdate;
end;



А теперь догадайся почему... ;)

04-11-2006 13:32 | Комментарий к предыдущим ответам
To Green:

Согласен почти во всём... ;) Только для динамических запросов я не пользуюсь ADD... ;)))


03-11-2006 01:02 | Комментарий к предыдущим ответам
Коллеги, о чем мы спорим? Я не призываю всех перейти на Add. В каком-то случае лучше хранить запросы в ресурсах, в каком-то создавать хранимые процедуры. А в случае построения сложного динамического запроса можно и Add воспользоваться. Мир многогранен!

02-11-2006 21:59

Так что, друзья, без Add никуда :)))


Хранимые процедуры рулят! ;)

02-11-2006 16:26
To Green:

Ты можешь смеяться, но... У меня есть запрос, который весит 131Кб... А теперь представь себе: сколько же надо вставить SQL.Add на такой запрос? Или как он будет читаться в присваении SQL.Text? Кроме того, у использования данных функций есть свой плюс: запросы можно редактировать без наличия исходников любым редактором ресурсов...

To voldan:

Нет, это не "мотоцикл", это оптимизация кода... Поверь мне... Я видел модули, которые весят по пол метра (более 100 000 строк), и, в большинстве своём, именно SQL.Add там и использовали... Как ты думаешь, другому программисту, который прийдёт на работу, будет хорошо ковыряться в таком коде? И ещё без форматирования... Хотя тебе видней...




01-11-2006 00:31 | Комментарий к предыдущим ответам
Конечно, на любителя, но вот лично я не использую метод Add. Sql.Text мне как-то более по душе.

Ну-ну. Ты может и не используешь, а вот SQL.Text как раз использует:

procedure TStrings.SetTextStr(const Value: string);
begin
//...
  Add(S);
//...
end;


Так что, друзья, без Add никуда :)))

31-10-2006 15:11
Конечно, на любителя, но вот лично я не использую метод Add. Sql.Text мне как-то более по душе. Но, опять же, дело вкуса.

31-10-2006 13:40 | Комментарий к предыдущим ответам
2 Куфенко Павел:

А что... Если длиные, то низя?!?! Вот тебе раз... Ну тогда держи немного кода, пока я здоров и в своём уме... ;)

Что-то ты слишком сложно завернул :) Проще было:

ADOQuery1.SQL.Text := '-- Здесь пятьдесят строк комментария запроса ;)'
  + '-- ...'
  + '-- ...'
  + '-- Все пятьдесят мне писать в ломы... ;)'
  + 'SELECT * FROM Employees';


А если серьезно, откуда такая неприязнь к SQL.Add? Если, например, нужно обрабатывать какие-либо данные и делать вставку в БД динамическим запросом, более удобную альтернативу вряд ли найти.

31-10-2006 13:28
To Павел
вот это мотоцикл?!! :)

31-10-2006 12:15 | Комментарий к предыдущим ответам

To Green:

А что... Если длиные, то низя?!?! Вот тебе раз... Ну тогда держи немного кода, пока я здоров и в своём уме... ;)

function LoadSQL(const ResourceID: Cardinal): string; overload;
begin
  with TResourceStream.CreateFromID(hInstance, ResourceID, RT_RCDATA) do
    try
      SetLength(Result, Size);
      if Size > 0 then ReadBuffer(Result[1], Size);
    finally
      Free;
    end;
end;

function LoadSQL(const ResourceID: Cardinal; const Arguments: array of const): string; overload;
begin
  Result := Format(LoadSQL(ResourceID), Arguments);
end;



Вот так выглядит большой запрос:

-- Здесь пяьтдесят строк комментария запроса ;)
-- ...
-- ...
-- Все пятьдесят мне писать в ломы... ;)

SELECT * FROM Employees


Выкидываем это дело в RC файл:

1 RCDARA "C:\BigSQL\select.sql"

А присвоение делаем вот так:

Query1.SQL.Text := LoadSQL(1);




31-10-2006 05:20
to Green

Да сидят там в Борланде ламеры, делать нечего им, и вместо того, чтоб дыры залатывать - они то выставляют обработчики, то сбрасывают, то выставляют, то сбрасывают... :)

Хочу в Борланд! :)

31-10-2006 05:17
Вы ведь согласны со мной, о рыцарь Green? :)

О чем речь, братан! Зачем ссориться? Давайте жить дружно! :)

Никогда на D5 не работал. Странно, зачем Борланд изменил код QueryChanged? От нечего делать, наверное...

31-10-2006 04:51
to  TPID

Вы что?!! :) Ссориться?!! :) Это не по рыцарски!

Никогда рыцари славного королевства не должны ссориться!

Вы ведь согласны со мной, о рыцарь Green? :)

31-10-2006 04:48
Но и Voldan не сдается! :)

Если использовать прекрасную систему программирования Delphi 5, то можно легко убедиться, что:

procedure TADOQuery.QueryChanged(Sender: TObject);
begin
  CommandText := FSQL.Text;
end;

Поэтому, Великие рыцари должны начинающим помогать и уточнять, что данный метод ориентирован на определенную версию! :)

Версионность - великое дело!!! :))))

31-10-2006 04:25 | Сообщение от автора вопроса
)))))))) Ребята, не ссорьтесь!!! Смешно на вас смотреть! Я вопрос задавал совсем про другое, но раз уж тут спор вышел, вставлю свои пять копеек и скажу, что как я понял, в Дельфи 7 запрос закрывается автоматически при изменении SQL, а в Д5 (как у меня) нет. Просто я уже с одним товарищем в аське этот вопрос обсуждал, и он с пеной у рта мне доказывал, что запрос закрывается сам, а у меня-то не закрывается :-)) Сравнили потом версии дельфи и пришли к консенсусу )))

31-10-2006 04:18
Ай-яй-яй, Green :)
Вы же славный Великий рыцарь! :)))


"Долой Green'а!" - кричала толпа. "Он недостоин почетного звания рыцаря!"
Из последних сил трясущимися руками Green набрал на клавиатуре следующий код:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ADOQuery1.SQL.Text := 'select * from sectors';
  ADOQuery1.Open;
  if ADOQuery1.Active then ShowMessage('Active') else ShowMessage('Not active');
  ADOQuery1.SQL.Text := 'select * from sectors';
  if ADOQuery1.Active then ShowMessage('Active') else ShowMessage('Not active');
end;


О, чудо! При изменении текста запроса запрос закрылся автоматически! Green спасен! :)
В чем же секрет? Обратимся к исходникам. При создании компонента TADOQuery к его свойству SQL цепляется обработчик, реагирующий на изменение текста запроса:

constructor TADOQuery.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FSQL := TStringList.Create;
  TStringList(FSQL).OnChange := QueryChanged; // Вот тут!
  Command.CommandTextAlias := 'SQL'; { Do not localize }
end;


Этот обработчик при изменении текста запроса закрывает его:

procedure TADOQuery.QueryChanged(Sender: TObject);
begin
  if not (csLoading in ComponentState) then
    Close; // Вот тут!
  CommandText := FSQL.Text;
end;


31-10-2006 03:52
Green, я цитирую Вас:
Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически

Это Ваши слова.

то есть, это значит:

Query.Close;
Query.SQL.Text := 'Select * from T';
Query.Open;

и вот тут.. :)

Query.SQL.Text := 'Select * from B'

вы утверждаете, что он все равно закроется автоматически

Ай-яй-яй, Green :)
Вы же славный Великий рыцарь! :)))



31-10-2006 03:47
Вот код:

Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически


У меня такой "код" компилятор даже не пропускает, а у тебя ошибка времени выполнения? :)))

31-10-2006 03:36
to Green

Вот код:

Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически


31-10-2006 03:23
Cannot Perform this operation on an open dataset

Что за код?

31-10-2006 02:34
изменении текста запроса он все равно закроется автоматически

А вот здесь Вы не правы. Нужно закрывать набор.
Cannot Perform this operation on an open dataset.

31-10-2006 02:12
а зачем использовать ADOQuery1.Active := false при ADOQuery1.ExecSQL?

В принципе это не нужно. Даже если компонент ранее содержал запрос, возвращающий данные и был открыт, то при изменении текста запроса он все равно закроется автоматически. Я так делаю скорее по привычке.

31-10-2006 00:32
а зачем использовать ADOQuery1.Active := false при ADOQuery1.ExecSQL?
если ADOQuery1 содержит набор данных, то понятное дело, но тогда наужно использовать метод Open или Active := true. Вы понимаете, для чего нужен метод ExecSQL?

31-10-2006 00:06 | Комментарий к предыдущим ответам
Хоть один человек вместо SQL.Add использует SQL.Text! ;)))

Это потому что у него запросы короткие :)

30-10-2006 23:21 | Сообщение от автора вопроса
Большое спасибо всем отвечающим, все работает замечательно.

30-10-2006 12:14

To Антон Григорьев:

Разрешите небольшие изменения в Вашему коду, если компонент TADOQuery уже подключён к соединению...

procedure TForm1.Button1Click(Sender:TObject);
begin
  ADOQuery1.Active := false;
  ADOQuery1.Connection.BeginTrans;
  try
    ADOQuery1.SQL.Text :='....';
    ADOQuery1.ExecSQL;
    // ...
    ADOQuery1.Active := false;
    ADOQuery1.SQL.Text :='....';
    ADOQuery1.ExecSQL;  // Допустим, здесь происходит ошибка
    // ...
    ADOQuery1.Connection.CommitTrans;
  except
    ADOQuery1.Connection.RollbackTrans;
    raise;
  end
end;



Так при изменении соединения не нужно быдет править код... ;)

P.S. Хоть один человек вместо SQL.Add использует SQL.Text! ;)))


30-10-2006 10:15
А зачем два раза ExecSQL? Вот так не проще?

begin
  ADOQuery1.Active := false;
  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add := '....';
  ADOQuery1.SQL.Add := '....';
  ADOQuery1.ExecSQL;
end;


30-10-2006 07:27
А вот и надо объединить все эти действия в транзакцию:

Button1.onClick(Sender:TObject);
begin
  ADOConnection1.BeginTrans;
  try
    ADOQuery1.Active := false;
    ADOQuery1.SQL.Text :='....';
    ADOQuery1.ExecSQL;
    ..
    ADOQuery1.Active := false;
    ADOQuery1.SQL.Text :='....';
    ADOQuery1.ExecSQL;<----Допустим, здесь происходит ошибка
    ..
    ADOConnection1.CommitTrans
  except
    ADOConnection1.RollbackTrans;
    raise
  end
end;


Добавьте свое cообщение

Вашe имя:  [Войти]
Ваш адрес (e-mail):На Королевстве все адреса защищаются от спам-роботов
контрольный вопрос:
Кто съел Красную шапочку?
в качестве ответа на вопрос или загадку следует давать только одно слово в именительном падеже и именно в такой форме, как оно используется в оригинале.
Надоело отвечать на странные вопросы? Зарегистрируйтесь на сайте.
Тип сообщения:
Текст:
Жирный шрифт  Наклонный шрифт  Подчеркнутый шрифт  Выравнивание по центру  Список  Заголовок  Разделительная линия  Код  Маленький шрифт  Крупный шрифт  Цитирование блока текста  Строчное цитирование
  • вопрос Круглого стола № XXX

  • вопрос № YYY в тесте № XXX Рыцарской Квинтаны

  • сообщение № YYY в теме № XXX Базарной площади
  • обсуждение темы № YYY Базарной площади
  •  
     Правила оформления сообщений на Королевстве

    Страница избранных вопросов Круглого стола.
      
    Время на сайте: GMT минус 5 часов

    Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter.
    Функция может не работать в некоторых версиях броузеров.

    Web hosting for this web site provided by DotNetPark (ASP.NET, SharePoint, MS SQL hosting)  
    Software for IIS, Hyper-V, MS SQL. Tools for Windows server administrators. Server migration utilities  

     
    © При использовании любых материалов «Королевства Delphi» необходимо указывать источник информации. Перепечатка авторских статей возможна только при согласии всех авторов и администрации сайта.
    Все используемые на сайте торговые марки являются собственностью их производителей.

    Яндекс цитирования