Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TADOQuery - не получаеться выполнить запрос 
:(
    Опции темы
KgCoder
  Дата 11.9.2010, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 6.3.2008
Где: KGstan

Репутация: нет
Всего: нет



Код

  with ADOQueryDB do
  try
    Close;
    SQL.Add('DELETE * FROM Diagnose WHERE ID = '+ IntToStr(ID) +' OR ParentID = '+ IntToStr(ID));
    ExecSQL;
  finally
    ShowMessage('Node #'+ IntToStr(ID) +' deleted from database.');
  end;


Пишет: ADOQueryDB: Cannot perform this operation on a closed dataset.

Подскажите ошибку...  smile 

Это сообщение отредактировал(а) KgCoder - 12.9.2010, 23:04
PM MAIL   Вверх
KgCoder
  Дата 11.9.2010, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 6.3.2008
Где: KGstan

Репутация: нет
Всего: нет



Нашел это: ADO Проблемы

Сделал так:
Код

  with ADOQueryDB do
  try
    Active := false;
    DataSource.Enabled := false;
    tmp_query := SQL.Text;
    SQL.Text := 'DELETE * FROM Diagnose WHERE ID = '+ IntToStr(ID) +' OR ParentID = '+ IntToStr(ID);
    ExecSQL;
  finally
    SQL.Text := tmp_query;
    Active := true;
    DataSource.Enabled := true;
    ShowMessage('Node #'+ IntToStr(ID) +' deleted from database.');
  end;


Теперь она выводит ошибку "Access violation"... 
PM MAIL   Вверх
БелАмор
Дата 11.9.2010, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: нет
Всего: 17



По поводу первого варианта

Вы добавляете строку к тому, что уже было в свойстве SQL. И что получается?
Либо перед добавлением очищайте свойство SQL, либо присвавайте напрямую SQL.Text
Свойство SQL имеет тип TStrings. Почитайте о TStrings, он используется практически везде.

По поводу второго варианта

1. "Active := false" и "Close" - это одно и то-же.
2.  "DataSource.Enabled := false"
    а) А у вас вообще назначено свойство ADOQueryDB.DataSource ?
    б) Если назначено, то зачем?  
3.
Цитата

tmp_query := SQL.Text;
...
SQL.Text := tmp_query;

Если в ADOQueryDB могут выполняться разные запросы, то формируйте их все каждый раз заново, не интересуясь, что там было в свойстве SQL раньше, а не занимайтесь сохранением/восстановлением чего-то, забитого в дизайн-тайм.
4.
Цитата

Active := true;

Active:=True или Open используются для запросов, возвращающих данные, т.е. для запросов с SELECT

PM   Вверх
KgCoder
Дата 12.9.2010, 00:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 6.3.2008
Где: KGstan

Репутация: нет
Всего: нет



Цитата(БелАмор @  11.9.2010,  20:22 Найти цитируемый пост)
Вы добавляете строку к тому, что уже было в свойстве SQL. И что получается?Либо перед добавлением очищайте свойство SQL, либо присвавайте напрямую SQL.TextСвойство SQL имеет тип TStrings. Почитайте о TStrings, он используется практически везде.

ADOQuery чист. Тем не менее, ошибка выходит и через SQL.Text и через SQL.Clear; SQL.Add;

Цитата(БелАмор @  11.9.2010,  20:22 Найти цитируемый пост)
1. "Active := false" и "Close" - это одно и то-же.2.  "DataSource.Enabled := false"    а) А у вас вообще назначено свойство ADOQueryDB.DataSource ?    б) Если назначено, то зачем?  3.Цитатаtmp_query := SQL.Text;...SQL.Text := tmp_query;Если в ADOQueryDB могут выполняться разные запросы, то формируйте их все каждый раз заново, не интересуясь, что там было в свойстве SQL раньше, а не занимайтесь сохранением/восстановлением чего-то, забитого в дизайн-тайм.4.ЦитатаActive := true;Active:=True или Open используются для запросов, возвращающих данные, т.е. для запросов с SELECT

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

Ориентируйтесь на первый пост. Там нету ничего лишнего и при этом она провоцирует ошибку.

Прикрепляю файл проекта. (Используются ADO, PNGComponents и VirtualTree).

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  Project.zip 998,26 Kb
PM MAIL   Вверх
Данкинг
Дата 12.9.2010, 01:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 35
Всего: 130



Код

with ADOQueryDB do
 begin
    Close;
    SQL.Clear;
    SQL.Text := 'DELETE * FROM Diagnose WHERE ID = '+ IntToStr(ID) +' OR ParentID = '+ IntToStr(ID);
    ExecSQL;
    ShowMessage('Node #'+ IntToStr(ID) +' deleted from database.');
  end;



--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
cat512
Дата 12.9.2010, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 438
Регистрация: 20.3.2007

Репутация: 1
Всего: 15



Цитата(KgCoder @ 11.9.2010,  15:29)
Код

  with ADOQueryDB do
  try
    Close;
    SQL.Add('DELETE * FROM Diagnose WHERE ID = '+ IntToStr(ID) +' OR ParentID = '+ IntToStr(ID));
    ExecSQL;
  finally
    ShowMessage('Node #'+ IntToStr(ID) +' deleted from database.');
  end;


Пишет: ADOQueryDB: Cannot perform this operation on a closed dataset.

Подскажите ошибку...  smile

Может проблема в запросе? Что там за звёздочка такая? 
PM MAIL   Вверх
Данкинг
Дата 12.9.2010, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Yersinia pestis
****


Профиль
Группа: Завсегдатай
Сообщений: 8302
Регистрация: 7.11.2006
Где: მოსკოვი

Репутация: 35
Всего: 130



Цитата(cat512 @  12.9.2010,  18:06 Найти цитируемый пост)
Может проблема в запросе? Что там за звёздочка такая?  

Вообще действительно: зачем звёздочка в delete? Хотя из-за этого должны быть глюки запроса, а не "closed dataset".


--------------------
There's nothing left but silent epitaphs.
PM MAIL WWW   Вверх
БелАмор
Дата 12.9.2010, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: нет
Всего: 17



Цитата(KgCoder @  12.9.2010,  00:37 Найти цитируемый пост)
ADOQuery чист.

Это не так. Вот здесь вы заполняете SQL:
Код

procedure TFormApplication.ListBoxInformationLoadDB(Node: PVirtualNode);
var
  Data: PDiagnose;
begin
  ListBoxInformation.Clear;
  Data := VirtualStringTreeDB.GetNodeData(Node);
  with ADOQueryDB do
  try
    Close;
    SQL.Text := 'SELECT * FROM '+ FocusedRichEdit +' WHERE DiagnoseID = '+ IntToStr(Data.ID);
    Open;
  finally
    First;
    while not Eof do
    begin
      ListBoxInformation.Items.Add(FieldByName('Content').AsString);
      Next;
    end;
  end;
end;

Кстати, здесь try-finally используется не по делу: вы пытаетесь работать с данными в любом случае, даже если при выполнении запрроса произошло исключение...
Цитата(KgCoder @  12.9.2010,  00:37 Найти цитируемый пост)
Тем не менее, ошибка выходит и через SQL.Text и через SQL.Clear; SQL.Add;

Тогда не знаю...
PM   Вверх
KgCoder
  Дата 12.9.2010, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 93
Регистрация: 6.3.2008
Где: KGstan

Репутация: нет
Всего: нет



Проблему решил!!!  smile 

Проблема заключалось в... не знаю в чём. В общем вот код процедур загрузки/создания/редактирования/удаления:
Код

procedure TFormApplication.VirtualStringTreeDBLoadDiagnose(Node: PVirtualNode;
  Data: PDiagnose);
begin
  with TADOQuery.Create(nil) do
  try
    Connection := ADOConnectionDB;
    SQL.Text := 'SELECT * FROM Diagnose WHERE ParentID = '+ IntToStr(Data.ParentID) +' AND Content ="'+ Data.Content +'"';
    Open;
    First;
  finally
    Data := VirtualStringTreeDB.GetNodeData(Node);
    Data^.ID := FieldByName('ID').AsInteger;
    Data^.ParentID := FieldByName('ParentID').AsInteger;
    Data^.Content := FieldByName('Content').AsString;
    Free;
  end;
end;

procedure TFormApplication.VirtualStringTreeDBCreateDiagnose(Node: PVirtualNode;
  Data: PDiagnose; NewText: WideString);
var
  ParentData: PDiagnose;
  ParentID: Integer;
begin
  with VirtualStringTreeDB do
  begin
    ParentData := GetNodeData(Node.Parent);
    if (SelectedCount > 0) then
      ParentID := ParentData.ID
    else
      ParentID := 0;
  end;
  with TADOQuery.Create(nil) do
  try
    Connection := ADOConnectionDB;
    SQL.Text := 'INSERT INTO Diagnose (ParentID, Content) VALUES ('+ IntToStr(ParentID) +', "'+ NewText +'")';
    ExecSQL;
  finally
    Data^.ID := 0;
    Data^.ParentID := ParentID;
    Data^.Content := NewText;
    VirtualStringTreeDBLoadDiagnose(Node, Data);
    Free;
  end;
end;

procedure TFormApplication.VirtualStringTreeDBUpdateDiagnose(Node: PVirtualNode;
  Data: PDiagnose; NewText: WideString);
begin
  with TADOQuery.Create(nil) do
  try
    Connection := ADOConnectionDB;
    SQL.Text := 'UPDATE Diagnose SET Content = "'+ NewText +'" WHERE ID = '+ IntToStr(Data.ID);
    ExecSQL;
  finally
    Data^.Content := NewText;
    Free;
  end;
end;

procedure TFormApplication.VirtualStringTreeDBDeleteDiagnose(Node: PVirtualNode;
  Data: PDiagnose);
begin
  with TADOQuery.Create(nil) do
  try
    Connection := ADOConnectionDB;
    SQL.Text := 'DELETE * FROM Diagnose WHERE ID = '+ IntToStr(Data.ID);
    ExecSQL;
  finally
    Free;
  end;
end;


То есть теперь ADOConnection создаётся при FormCreate, а ADOQuery отдельно для каждого действия. Теперь ругайте... может нагрузка больщая? Или чего не правильно?  smile 
PM MAIL   Вверх
БелАмор
Дата 13.9.2010, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 10.6.2010
Где: Россия

Репутация: нет
Всего: 17



Цитата(KgCoder @  12.9.2010,  22:14 Найти цитируемый пост)
То есть теперь ADOConnection создаётся при FormCreate, а ADOQuery отдельно для каждого действия. Теперь ругайте... 

Вполне нормальный подход. Ничего особо плохого в нём нет. Даже есть плюсы, в частности, привычка писать программу кодом...
Хотел бы только обратить внимание несколько моментов:
1. После открытия датасета (который до этого был в закрытом состоянии) текущей записью всегда становится первая, поэтому вызывать First в этом случае излишне.
2. Вообще, сложные строки удобно формировать с помощью функции Format. Это гораздо нагляднее, чем куча плюсов с апострофами, вызовами IntToStr и подобного. Я имею в виду действительно сложные строки, в данном случае это не очень актуально.
3. Данные, текстовое представление которых зависит от региональных настроек (например, дата), передавайте в запрос только через параметры. В данном случае таких данных не наблюдается, но наблюдается стремление писать весь запрос текстом...
4. Таки уберите уж звёздочку между DELETE и FROM... 
PM   Вверх
Deniz
Дата 14.9.2010, 05:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 8
Всего: 44



Цитата(KgCoder @  13.9.2010,  00:14 Найти цитируемый пост)
Теперь ругайте.
Ну если уж сам просишь, извольте.
Первым делом посмотри как работает блок try finally end.
Далее, про Open + First уже сказали, First не нужен.
Все тексты запросов к БД лучше оформлять с параметрами.
Зачем в каждой процедуре создавать и удалять ADOQuery? Можно одну кинуть на форму и с ней работать.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0916 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.