If you run your application Delphi will restore the open
or closed
state that the dataset had in the Delphi form designer.
If there is an error Delphi can quitly drop this and close the dataset.
Also it’s possible that you accidently closed the dataset in the designer, after with it no longer auto-opens on ptogram start.
When it’s time to use the dataset you will get this error because the dataset is closed.
One option is to explicitly open the dataset in the FormCreate event and add error handling code there, this will allow you to see the error message and debug from there.
procedure TForm1.FormCreate(sender: TObject);
begin
try
MyDBFTable.Open;
except on exception e do
WriteErrorToLogFile('Cannot open MyDBFTable, error is: ' + e.message);
// or
//ShowMessage('Cannot open MyDBFTable, error is: ' + e.message);
end; {try}
end;
I always do opening of datasets explicitly in FormCreate because this allows me to log any errors. If a client app has an exception it gets emailed to me automatically.
Проблема: При нажатии на кнопку в программе появляется сообщение об ошибке.
Cannot perform this operation on a closed DataSet
Технические детали: На форме есть DataSet (если вы используете компоненты ADO, тогда это будет ADOQuery, ADOTable, Если UniDac — UniQuery, UniTable… В прочем это не играет большой роли для текущей ситуации). На кнопке был код, который обрабатывал некие данные находящиеся в DataSet’е, при обращении к нему появилась ошибка:
Cannot perform this operation on a closed DataSet
Инструментарий: Delphi XE
Решение: Проблема в том что мы пытаемся обратится к закрытому набору данных DataSet’а, для того чтобы решить данную проблемы пере обращением его нужно открыть.
DataSet.Active
Я к примеру использую процедуру для обновления DataSet’a, если DataSet открыт — обновляем, иначе открываем. Это не универсальное решение, но его можно использовать в большинстве случаев.
procedure RefreshDataSet(DataSet: TDataSet);
begin
if DataSet.Active then
DataSet.Refresh
else
DataSet.Open;
end;
Пример использования:
RefreshDataSet(ADOQuery1);
RefreshDataSet(UniQuery1);
SashaBucheR 0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
||||
1 |
||||
11.07.2013, 12:07. Показов 50401. Ответов 11 Метки нет (Все метки)
Добрый день! Есть такая проблемка: в наследство досталась программа, которая связывается с SQL сервером. Поставил вместо старого sql 2005 b поменял в ADOConnection путь. Теперь выдает ошибку: cannot perform this operation on a closed dataset (сама программа загружается и данные отображаются, это только когда начинаешь редактировать). В коде есть вот такая ерунда:
Пробовал и Integrated Security и через Юзера, толку нет. Самое интересное, что есть еще программа, которая работает с этой же базой, она работает полностью и редактировать данные можно. Где все-таки косяк? В Делфи или SQL (на сервере проверка подлинности стоит и Windows и SQl)?
__________________
0 |
476 / 390 / 111 Регистрация: 24.04.2012 Сообщений: 1,619 Записей в блоге: 3 |
|
11.07.2013, 12:31 |
2 |
cannot perform this operation on a closed dataset «невозможно выполнить операцию при закрытом наборе данных», т.е. при редактировании идет обращение к DataSet’у, а он в свою очерез закрыт. А этот код скорее всего с ошибкой никак не связян, т.к. это строка подключения к БД.
0 |
0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
|
11.07.2013, 13:37 [ТС] |
3 |
Я понял, что это строка подключения. Просто думал, что он подключается как-то с ограниченным доступом… Сейчас гляну DataSet. Вот только я слабоват… Нашел где DataSet, а что там проверить, прописать, чтобы он был открыт)
0 |
966 / 641 / 97 Регистрация: 01.11.2012 Сообщений: 1,447 |
|
11.07.2013, 15:01 |
4 |
SashaBucheR, попробуйте у всех Датасетов (ADOTable, ADODataSet, ADOQuery), которые были подключены к вашему ADOConnection изменить свойство Active на значение True.
0 |
0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
|
11.07.2013, 15:24 [ТС] |
5 |
Это во время CreateForm
0 |
0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
|
11.07.2013, 15:46 [ТС] |
6 |
Когда подключаюсь под sa сначала выдает такие две картинки. А потом опять «cannot perform this operation on a closed dataset»
0 |
476 / 390 / 111 Регистрация: 24.04.2012 Сообщений: 1,619 Записей в блоге: 3 |
|
12.07.2013, 05:12 |
7 |
Картинки это конечно хорошо, но еще бы и код немешало бы посмотреть, который их вызывает.
0 |
SashaBucheR 0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
||||||||
12.07.2013, 08:45 [ТС] |
8 |
|||||||
Выбивает на строке OpenADOTables
Добавлено через 36 минут
0 |
476 / 390 / 111 Регистрация: 24.04.2012 Сообщений: 1,619 Записей в блоге: 3 |
|
15.07.2013, 09:58 |
9 |
а код OpenADOTables?
0 |
SashaBucheR 0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
||||||||
16.07.2013, 11:11 [ТС] |
10 |
|||||||
В том коде, что открытие карточки, я поставил проверку состояния DataSet:
Выбивает Open, то есть, как бы Dataset активен…
0 |
Bit_Man 476 / 390 / 111 Регистрация: 24.04.2012 Сообщений: 1,619 Записей в блоге: 3 |
||||||||||||
17.07.2013, 10:03 |
11 |
|||||||||||
Выбивает на строке OpenADOTables Если так то проверяй Таблицы после открытия
выбивает при создании новой карточки
Добавлено через 3 минуты
??
0 |
0 / 0 / 0 Регистрация: 11.07.2013 Сообщений: 7 |
|
18.07.2013, 11:39 [ТС] |
12 |
Там действительно была проблема в таблицах. В ComboBox как-то DataSource сбились. Вот только теперь выдает «Exception class EDatabaseError with message: Circular datalinks are not allowed» при создании формы. Добавлено через 2 часа 22 минуты
0 |
Roberto Nicchi wrote:
> Il 28/07/2016 02:13, Eivind Bakkestuen [NDD] ha scritto:
> > > I’m wondering how a TnxTable is closed automatically.
> >
> > Afaik, it wouldn’t be.
> >
> > Get the callstacks from your customers and see where it happens;
> > perhaps there’s a clue.
> >
> This is one:
>
> rigdoc_table: Cannot perform this operation on a closed dataset.
>
>
> [007C207D] Data.DB.DatabaseError
> [0044E107] System.SysUtils.AnsiCompareText
> [007D73C1] Data.DB.TDataSet.CheckActive
> [00B3E0A4] nxdb.TnxDataset.CreateBlobStream (Line 8732, «nxdb.pas»)
> [007CE72A] Data.DB.TBlobField.GetAsAnsiString
> [007CF3AC] Data.DB.TMemoField.GetAsString
It looks like your code is attempting to do a field-related function
here before checking the table is active.
……
>
>
> and this is another one
>
> tesdoc_table: Cannot perform this operation on a closed dataset.
>
>
> [007C207D] Data.DB.DatabaseError
> [0080C0F7] JfCollection.TJfCollection.Opt
> [007D73C1] Data.DB.TDataSet.CheckActive
> [007DB7E4] Data.DB.TDataSet.CheckBrowseMode
> [007DAC99] Data.DB.TDataSet.BeginInsertAppend
> [007DA986] Data.DB.TDataSet.Append
> [01E01028] gestione_documenti.attiva_gestione_documenti (Line 1269,
> «gestione_documenti.pas») [02AE516B] main.Tmain_form.esegui_procedura
This one looks like it is trying to do an Append without checking to
see if the dataset is active.
> (Line 3633, «main.pas») [02AEA9E4] main.Tmain_form.JfBitBtn1Click
> (Line 4770, «main.pas») [00657CC3] Vcl.Controls.TControl.Click
……
>
>
> not sure about Nexusdb version. I should add the NexusDb version to
> the Eurekalog report.
You may want to check your table for any dependencies which assume that
the component is active when you open the form. If it’s supposed to be
active then maybe the ActiveRuntime is set to False?
—
Regards,
Will Owyong
(GMT+10: Newcastle & Parramatta, Australia)
Moderators: gto, EgonHugeist, olehs
-
marsupilami
- Platinum Boarder
- Posts: 1699
- Joined: 17.01.2011, 14:17
[solved] Cannot perform this operation on a closed dataset
Hello
I finally have my first testproject and have a problem. In most of my Projects I use a structure similar to this:
Code: Select all
ZConnection1.Connect;
ZConnection1.StartTransaction;
try
[do someting]
ZConnection1.Commit;
except
ZConnection1.Rollback;
end;
ZConnection1.Disconnect;
With Zeos 7 this raises an exception on commit: «XQuery: Cannot perform this operation on a closed dataset.», where XQuery is a closed query.
When the program subsequently tries to execute the rollback I get the exception «Invalid operation in AutoCommit mode».
Taking a look at the database, I see that the Transaction has been committed. But I wonder why the Connection would do anything to an inactive Query and why it does this after the commit?
This happens with the current version of http://svn.code.sf.net/p/zeoslib/code-0 … es/testing as well as with the latest version of http://svn.code.sf.net/p/zeoslib/code-0/trunk on Delphi XE2 and Firebird 2.1. The transaction isolation level is set to tiReadCommitted.
Best regards,
Jan
-
marsupilami
- Platinum Boarder
- Posts: 1699
- Joined: 17.01.2011, 14:17
Post
by marsupilami » 13.08.2012, 19:17
Hello,
The problem seems to have resolved itself somehow.
I am sorry for the trouble…
Best regards,
Jan
-
patyit
- Junior Boarder
- Posts: 37
- Joined: 10.02.2012, 18:39
Post
by patyit » 18.08.2012, 17:04
Hi all !
Jan is lucky, his problem is resolved itself !
But mine is not !
Lazarus 1.1, FPC 2.6.0, Zeos svn Testng (also Trunc) latest, Firebird 2.5
…
Database.StartTransaction;
try
Query1.ApplyUpdates;
Query2.ApplyUpdates;
Query3.ApplyUpdates;
Database.Commit; // <— Error message: ‘External: SIGSEGV’.
except
Database.Rollback;
… // error handling an back to edit data
Exit;
end;
QPrometz.CommitUpdates;
QPromett.CommitUpdates;
QPromet.CommitUpdates;
…
The full error message is :
Project RobFinPro raised exception class ‘External: SIGSEGV’.
In file ‘/home/patyi/lazarus-svn/zeos7_test/src/component/ZAbstractDataset.pas’ at line 641:
CachedResultSet.DisposeCachedUpdates;
I’m developing an ERP like (big) application and this code construction is very important !
I found bugreport for this : http://zeosbugs.firmos.at/view.php?id=206
Any progress ?
Best regards, Patyi
-
ism
- Zeos Test Team
- Posts: 202
- Joined: 02.10.2010, 20:48
Post
by ism » 18.08.2012, 17:26
Lazarus 1.1 ? What you want ?
On older stable versions of the same ?
Lazarus 1.0.8 fpc 2.6.0
-
ism
- Zeos Test Team
- Posts: 202
- Joined: 02.10.2010, 20:48
Post
by ism » 18.08.2012, 17:27
Lazarus 1.0.8 fpc 2.6.0
-
EgonHugeist
- Zeos Project Manager
- Posts: 1936
- Joined: 31.03.2011, 22:38
Post
by EgonHugeist » 19.08.2012, 11:44
patyit,
Nope i don’t think there was any further progress. Like i wrote on the BugReport i wanted to have some testers for the added code. I had no time to add a testcase to the testsuites we have. Maybe you can help me here?
Can you determime the SIGDEV?
Ism, he uses the new testing-branch on the other hand it would not be possible to have procedure DisposeCachedUpdates avialable, i think.
Michael
-
patyit
- Junior Boarder
- Posts: 37
- Joined: 10.02.2012, 18:39
Post
by patyit » 19.08.2012, 16:03
ism,
I’m using exactly that rev !
Michael,
I can write a small test application with data to demonstrate and test this bug.
I can test the changes, in test application and on production application with live data.
At least I can tell You it is ok or not.
By now : External: SIGSEGV when try to execute CachedResultSet.DisposeCachedUpdates
-
patyit
- Junior Boarder
- Posts: 37
- Joined: 10.02.2012, 18:39
Post
by patyit » 19.08.2012, 18:27
Some additional information :
I made a test, simulating wrong data witch is cause foreign key violation on ApplyUpdates, the changes is rolled back, and I can edit data correctly to solve the problem. It seams to Rollback is working correctly …
-
EgonHugeist
- Zeos Project Manager
- Posts: 1936
- Joined: 31.03.2011, 22:38
Post
by EgonHugeist » 19.08.2012, 19:23
patyit,
having a test-case would be fine. For me personally would it be the best help if you are able to add a test to our testsuites directly. So we can test the functionallity allways. However a test case or a patch to fix this issue would be great…
My thougths about the sequence the code should work now:
Take care TZConnection.AutoCommit = False and about the Transaction isolation levels…
try
Query1.ApplyUpdates;
Query2.ApplyUpdates;
Query3.ApplyUpdates; // <— Error message: ‘External: SIGSEGV’. This IS ok for me, if values are missing or the constraint cascade Rules making trouble! Btw. i implemented a TZQuery.Option doUpdateMasterFirst (only available with Zeos) which allows now to update a ForeignKey constraint in the MasterTable first and then all child-Tables.. (Here i allready made some tests and the work nice)
Database.Commit; //IF all Updates are done then this is not neccessary with Zeos if AutoCommit is True on the other hand it should work like expected.. I think this is the issue you want ot point me?!
except
Database.Rollback; //Roleback should dispose all done updates of the RowAccessor and calls DisposeUpdatesCh
… // error handling an back to edit data
Exit;
end;
QPrometz.CommitUpdates; // here i don’t understand you… Database.Commit should do this before.
QPromett.CommitUpdates;
QPromet.CommitUpdates;
Michael
-
patyit
- Junior Boarder
- Posts: 37
- Joined: 10.02.2012, 18:39
Commit error
Post
by patyit » 04.09.2012, 14:46
Hi all !
procedure TZAbstractConnection.Commit;
var
ExplicitTran: Boolean;
i: Integer;
begin
CheckConnected;
CheckNonAutoCommitMode;
ExplicitTran := FExplicitTransactionCounter > 0;
if FExplicitTransactionCounter < 2 then
//when 0 then AutoCommit was turned off, when 1 StartTransaction was used
begin
ShowSQLHourGlass;
try
try
// ***** rem by patyi *****
// for i := 0 to FDatasets.Count -1 do
// THack_ZAbstractDataset(FDatasets).DisposeCachedUpdates;
FConnection.Commit;
finally
FExplicitTransactionCounter := 0;
if ExplicitTran then
AutoCommit := True;
end;
finally
HideSQLHourGlass;
end;
DoCommit;
end
else
Dec(FExplicitTransactionCounter);
end;
I modyfied this procedure and seams to work good with fallowing program construction :
…
Database.StartTransaction;
try
Query1.ApplyUpdates;
Query2.ApplyUpdates;
Query3.ApplyUpdates;
Database.Commit; // earlier I got Error message: ‘External: SIGSEGV’.
except
Database.Rollback;
… // error handling an back to edit data
Exit;
end;
Query1.CommitUpdates; // this clear cached buffer,
Query2.CommitUpdates; // need because I’m modyfied the
Query3.CommitUpdates; // TZAbstractConnection.Commit procedure
…
As I said it works good, but I’m not shore about memory leaks …
-
EgonHugeist
- Zeos Project Manager
- Posts: 1936
- Joined: 31.03.2011, 22:38
Post
by EgonHugeist » 04.09.2012, 20:29
patyit,
ok this a sloution and an example to check the issue. I hope i’ll find the time next week to find out why THack_ZAbstractDataset(FDatasets).DisposeCachedUpdates; does raise exceptions.
-
EgonHugeist
- Zeos Project Manager
- Posts: 1936
- Joined: 31.03.2011, 22:38
Post
by EgonHugeist » 14.09.2012, 10:38
patyit,
I can do what i want. No way to reproduce the issue.
i use this code:
Code: Select all
procedure TZTestMasterDetailCase.TestClientDatasetWithForeignKey_ApplyUpdates;
var
SQLMonitor: TZSQLMonitor;
I: Integer;
procedure SetTheData(Index: Integer);
begin
MasterQuery.Append;
MasterQuery.FieldByName('dep_id').AsInteger := TestRowID + Index;
if Connection.UTF8StringsAsWideField or ( Connection.DbcConnection.GetEncoding = ceAnsi) then
MasterQuery.FieldByName('dep_name').AsString := 'öäüüäö'
else
MasterQuery.FieldByName('dep_name').AsString := Utf8Encode(WideString('öäüüäö'));
MasterQuery.FieldByName('dep_shname').AsString := 'abc';
if Connection.UTF8StringsAsWideField or (Connection.DbcConnection.GetEncoding = ceAnsi) then
MasterQuery.FieldByName('dep_address').AsString := 'A adress of öäüüäö'
else
MasterQuery.FieldByName('dep_address').AsString := Utf8Encode(WideString('A adress of öäüüäö'));
CheckEquals(True, (MasterQuery.State = dsInsert), 'MasterQuery Insert-State');
MasterQuery.Post;
DetailQuery.Append;
DetailQuery.FieldByName('p_id').AsInteger := TestRowID + Index;
DetailQuery.FieldByName('p_dep_id').AsInteger := TestRowID + Index;
if Connection.UTF8StringsAsWideField or (Connection.DbcConnection.GetEncoding = ceAnsi) then
DetailQuery.FieldByName('p_name').AsString := 'üäööäü'
else
DetailQuery.FieldByName('p_name').AsString := Utf8Encode(WideString('üäööäü'));
DetailQuery.FieldByName('p_begin_work').AsDateTime := now;
DetailQuery.FieldByName('p_end_work').AsDateTime := now;
DetailQuery.FieldByName('p_picture').AsString := '';
DetailQuery.FieldByName('p_resume').AsString := '';
DetailQuery.FieldByName('p_redundant').AsInteger := 5;
DetailQuery.Post;
CheckEquals(True, (DetailQuery.State = dsBrowse), 'MasterQuery dsBrowse-State');
CheckEquals(True, (MasterQuery.State = dsBrowse), 'MasterQuery dsBrowse-State');
end;
begin
//Connection.AutoCommit := False;
Connection.TransactIsolationLevel := tiReadCommitted;
Connection.StartTransaction;
SQLMonitor := TZSQLMonitor.Create(nil);
SQLMonitor.Active := True;
MasterQuery.SQL.Text := 'SELECT * FROM department ORDER BY dep_id';
MasterQuery.CachedUpdates := True;
MasterQuery.Open;
DetailQuery.SQL.Text := 'SELECT * FROM people';
DetailQuery.MasterSource := MasterDataSource;
DetailQuery.MasterFields := 'dep_id';
DetailQuery.LinkedFields := 'p_dep_id';
DetailQuery.CachedUpdates := True;
DetailQuery.Open;
SetTheData(0); //Add 1 line/DataSet
try
try
DetailQuery.ApplyUpdates; //-> crash because of the cascade rules
MasterQuery.ApplyUpdates;
Connection.Commit;
Fail('Wrong ApplayUpdates behavior!');
except
SetTheData(1); //Add some more lines
DetailQuery.Options := DetailQuery.Options + [doUpdateMasterFirst];
MasterQuery.ApplyUpdates;
DetailQuery.ApplyUpdates;
Connection.Commit;
CheckEquals(True, (MasterQuery.State = dsBrowse), 'MasterQuery Browse-State');
CheckEquals(True, (DetailQuery.State = dsBrowse), 'DetailQuery Browse-State');
MasterQuery.SQL.Text := 'delete from people where p_id = '+IntToStr(TestRowID+1);
MasterQuery.ExecSQL;
MasterQuery.SQL.Text := 'delete from department where dep_id = '+IntToStr(TestRowID+1);
MasterQuery.ExecSQL;
end;
finally
MasterQuery.SQL.Text := 'delete from people where p_id = '+IntToStr(TestRowID);
MasterQuery.ExecSQL;
MasterQuery.SQL.Text := 'delete from department where dep_id = '+IntToStr(TestRowID);
MasterQuery.ExecSQL;
SQLMonitor.Free;
end;
end;
Waht i’m doing wrong?
Edit:
issue confirmed and is not solvable (Each second cast of the AbstractDataSet uses a pointer to a IZCachedResultSet except DXE2 up) so i’ve added a difine to exclude this code.
Issue is gone. Patch done 1837
Confirmed?
-
patyit
- Junior Boarder
- Posts: 37
- Joined: 10.02.2012, 18:39
Post
by patyit » 20.09.2012, 23:02
Hi EgonHugeist !
I confirmed the issue is gone, at list on Lazarus 1.1, FPC 2.6.1, on XUbuntu,
Win XP and Win 7 tested with my live multiplatform application.
«Unfortunately» I don’t have Delphi (fortunately have Lazarus) that I can’t test under Delphi.
So now I don’t need to call CommitUpdates after Commit ?
Thank for help ! Patyi.
-
EgonHugeist
- Zeos Project Manager
- Posts: 1936
- Joined: 31.03.2011, 22:38
Post
by EgonHugeist » 21.09.2012, 05:12
patyit,
thank you for confirm the commit behavior.
So now I don’t need to call CommitUpdates after Commit ?
Yes that’s right. CommitUpdates did check the BrowseMode and Clear the Buffer.
Thought the Sequence should be handled like you and others did proprose and in this case CommitUpdates is a deprecated procedure.
Can you post something on Mantis to close this issue?
Через поиск в абд попробовал найти сотрудника. В строке поиска ввёл саба и на экране появилось предупреждение:недопустимое имя столбца саба. Я нажал ок и на экране новое предупреждение Cannot perform this operation on a closed dataset». До этого все работало хорошо. Сталкивались ли с подобным и как решали? 1 год 5 месяцев назад
#ссылка |
1 ответ
Помогла простая перезагрузка 1 год 5 месяцев назад
#ссылка |
Добавить ответ
Для добавления сообщений на форуме вам необходимо зарегистрироваться и указать мобильный телефон в своем профиле (зачем?)
ЗАДАН
1 год 5 месяцев назад
По каждому вопросу/ответу можно добавлять комментарии. Комментарии предназначены для уточнения вопроса/ответа.
15 hours ago, bazzer747 said:
A suggestion above said to close the query first before opening it and this has worked, so another confusing event here — it cannot work on a closed dataset but after closing it it will open. Who or what closes a dataset? Nothing I do in the application specifically closes any dataset. Many times I respecify the query to change parameters but never knowingly close it.
That might have been me.
Generally, when you change the SQL text, a re-prepare is needed. That cannot be done on an open query. Not your problem above.
When you change the parameter values, the query needs to be re-executed (in a prepared state) and that entails close + re-open.
In a lot of cases the DAC will help you with this (like in a master-detail relationship) and i can confess that back when it took me some time to understand this.
You DAC should offer different ways of handling this, IMHO.
15 hours ago, bazzer747 said:
Who or what closes a dataset?
I cannot answer that (no FireDAC sources), @Uwe Raabe pointed in the right direction.
I would put an event handler on the query’s OnClose and a brekapint in that handler. Then look at the call-stack and put breakpoints below that. Eventually you will find the «culprit».
One more thing, you use a method called «Open» that takes the parameter value as argument. To me that sound like something you do only once.
When the value is changed, some other method should be used. Maybe something like «qQueryname.Refresh([ cYear ] );«. But again, i do not know.
I have a lot of [pseudocode]:
aQ.Params[0].AsInteger := aVar;
if aQ.Open then aQ.Refresh else aQ.Open;
HTH