Ошибка cannot perform this operation on a closed dataset

SashaBucheR

0 / 0 / 0

Регистрация: 11.07.2013

Сообщений: 7

1

11.07.2013, 12:07. Показов 53978. Ответов 11

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Добрый день! Есть такая проблемка: в наследство досталась программа, которая связывается с SQL сервером. Поставил вместо старого sql 2005 b поменял в ADOConnection путь. Теперь выдает ошибку: cannot perform this operation on a closed dataset (сама программа загружается и данные отображаются, это только когда начинаешь редактировать). В коде есть вот такая ерунда:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
begin
  Application.ProcessMessages;
  sConnection := 'Provider=SQLOLEDB.1;' +
                    'Integrated Security=SSPI;' +
                   // 'Persist Security Info=False;'+
                  //  'User ID=sа;'+
                    'Initial Catalog='+ ConfigParams.FindParam('DATABASE').Value+';'+
                    'Data Source='+ ConfigParams.FindParam('SERVER-GETSQ').Value+';'+
                    'Use Procedure for Prepare=1;'+
                    'Auto Translate=True;'+
                    'Packet Size=4096;'+
                    'Workstation ID='+s+ ';'+
                    'Use Encryption for Data=False;'+
                    'Tag with column collation when possible=False';
end;

Пробовал и Integrated Security и через Юзера, толку нет. Самое интересное, что есть еще программа, которая работает с этой же базой, она работает полностью и редактировать данные можно. Где все-таки косяк? В Делфи или SQL (на сервере проверка подлинности стоит и Windows и SQl)?



0



478 / 391 / 112

Регистрация: 24.04.2012

Сообщений: 1,622

Записей в блоге: 3

11.07.2013, 12:31

2

Цитата
Сообщение от SashaBucheR
Посмотреть сообщение

cannot perform this operation on a closed dataset

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



0



0 / 0 / 0

Регистрация: 11.07.2013

Сообщений: 7

11.07.2013, 13:37

 [ТС]

3

Я понял, что это строка подключения. Просто думал, что он подключается как-то с ограниченным доступом… Сейчас гляну DataSet. Вот только я слабоват… Нашел где DataSet, а что там проверить, прописать, чтобы он был открыт)
DataSet.Open;?



0



969 / 644 / 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

Ошибка "Cannot perform this operation on a closed dataset"

Это во время CreateForm



0



0 / 0 / 0

Регистрация: 11.07.2013

Сообщений: 7

11.07.2013, 15:46

 [ТС]

6

Когда подключаюсь под sa сначала выдает такие две картинки.

Ошибка "Cannot perform this operation on a closed dataset"

Ошибка "Cannot perform this operation on a closed dataset"

А потом опять «cannot perform this operation on a closed dataset»



0



478 / 391 / 112

Регистрация: 24.04.2012

Сообщений: 1,622

Записей в блоге: 3

12.07.2013, 05:12

7

Картинки это конечно хорошо, но еще бы и код немешало бы посмотреть, который их вызывает.



0



SashaBucheR

0 / 0 / 0

Регистрация: 11.07.2013

Сообщений: 7

12.07.2013, 08:45

 [ТС]

8

Выбивает на строке OpenADOTables

Delphi
1
2
3
4
5
6
7
procedure TDM.DataModuleCreate(Sender: TObject);
begin
    ConfigParams := TParams.Create;
    LoadConfig(ExtractFilePath(Application.ExeName)+'config.ini');
    BuildConnection;
    OpenADOTables
end;

Добавлено через 36 минут
cannot perform this operation on a closed dataset например выбивает при создании новой карточки, вот код:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
procedure TfrmCardsIn.NewInvoiceIn;
var
    mR : integer;
begin
    SetEnebledControl(ATYPE);
    DM.tblInvoiceIn.Append;
    DM.tblInvoiceIn['TYPE'] := ATYPE;
    case ATYPE of
    0:
    begin
        DM.tblInvoiceIn['XDSTID']:= '99999';
        DM.tblInvoiceIn['XSRCID']:= '0';
        DM.tblInvoiceIn.FieldByName('GUID').Value := DM.tblInvoiceMax.FieldByName('AMAX').AsInteger + 1;
        DM.tblInvoiceIn.FieldByName('SERIES').Value := DM.tblMaxNumber.FieldByName('SERIES').AsString ;
        DM.tblInvoiceIn.FieldByName('ANUMBER1').Value := DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ANUMBER2').Value := DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ADATE').Value := StrToDate(DM.ConfigParams.FindParam('WorkDate').Value);
        DM.tblInvoiceIn.FieldByName('DSTAMOUNT').Value := 0;
        DM.tblInvoiceIn.FieldByName('SRCAMOUNT').Value := 0;
    end;
    1:
    begin
        DM.tblInvoiceIn['XDSTID']:= '0';
        DM.tblInvoiceIn['XSRCID']:= '0';
        DM.tblInvoiceIn.FieldByName('GUID').Value := DM.tblInvoiceMax.FieldByName('AMAX').AsInteger + 1;
        DM.tblInvoiceIn.FieldByName('SERIES').Value := DM.tblMaxNumber.FieldByName('SERIES').AsString ;
        DM.tblInvoiceIn.FieldByName('ANUMBER1').Value := DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ANUMBER2').Value := DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ADATE').Value := StrToDate(DM.ConfigParams.FindParam('WorkDate').Value);
        DM.tblInvoiceIn.FieldByName('DSTAMOUNT').Value := 0;
        DM.tblInvoiceIn.FieldByName('SRCAMOUNT').Value := 0;
 
        DM.tblMinNumber.Parameters.ParamByName('@SELFDIRID').Value := DM.tblInvoiceIn.FieldByName('XDSTID').AsString;
        DM.tblMinNumber.Open;
        DM.tblInvoiceIn.FieldByName('SERIES').AsString := DM.tblMinNumber.FieldByName('SERIES').AsString;
        DM.tblInvoiceIn.FieldByName('ANUMBER1').AsInteger := DM.tblMinNumber.FieldByName('ANUMBER').AsInteger;
        DM.tblInvoiceIn.FieldByName('ANUMBER2').AsInteger := DM.tblMinNumber.FieldByName('ANUMBER').AsInteger;
        DM.tblMinNumber.Close
    end;
    2:
    begin
        DM.tblInvoiceIn['XDSTID']:= '0';
        DM.tblInvoiceIn['XSRCID']:= '99999';
        DM.tblInvoiceIn.FieldByName('GUID').Value := DM.tblInvoiceMax.FieldByName('AMAX').AsInteger + 1;
        DM.tblInvoiceIn.FieldByName('SERIES').Value := DM.tblMaxNumber.FieldByName('SERIES').AsString ;
        DM.tblInvoiceIn.FieldByName('ANUMBER1').Value := 0;//DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ANUMBER2').Value := 0;//DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ADATE').Value := StrToDate(DM.ConfigParams.FindParam('WorkDate').Value);
        DM.tblInvoiceIn.FieldByName('DSTAMOUNT').Value := 0;
        DM.tblInvoiceIn.FieldByName('SRCAMOUNT').Value := 0;
 
    end;
    3:
    begin
        DM.tblInvoiceIn['XDSTID']:= '0';
        DM.tblInvoiceIn['XSRCID']:= '99999';
        DM.tblInvoiceIn.FieldByName('GUID').Value := DM.tblInvoiceMax.FieldByName('AMAX').AsInteger + 1;
        DM.tblInvoiceIn.FieldByName('SERIES').Value := DM.tblMaxNumber.FieldByName('SERIES').AsString ;
        DM.tblInvoiceIn.FieldByName('ANUMBER1').Value := 0;//DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ANUMBER2').Value := 0;//DM.tblMaxNumber.FieldByName('ANUMBER').AsInteger  + 1;
        DM.tblInvoiceIn.FieldByName('ADATE').Value := StrToDate(DM.ConfigParams.FindParam('WorkDate').Value);
        DM.tblInvoiceIn.FieldByName('DSTAMOUNT').Value := 0;
        DM.tblInvoiceIn.FieldByName('SRCAMOUNT').Value := 0;
 
    end;
 
    end;
 
 
    Mr := frmEditCard.ShowModal;
    if mR = mrOK then
    begin
        try
            DM.tblInvoiceIn.Post;
            case ATYPE of
            0: DM.qryInvoiceIn.Requery;
            1: DM.qryInvoiceReplace.Requery;
            2: DM.qryInvoiceRemove.Requery;
            3: DM.qryInvoiceSpoil.Requery;
            end;
            //(dsCards.DataSet).Refresh;
            dsCards.DataSet.Locate('GUID',DM.tblInvoiceIn['GUID'],[])
        except
            on E: Exception do
            begin
                ShowMessage(E.Message);
                DM.tblInvoiceIn.Cancel
            end
        end;
    end
    else DM.tblInvoiceIn.Cancel
end;



0



478 / 391 / 112

Регистрация: 24.04.2012

Сообщений: 1,622

Записей в блоге: 3

15.07.2013, 09:58

9

а код OpenADOTables?



0



SashaBucheR

0 / 0 / 0

Регистрация: 11.07.2013

Сообщений: 7

16.07.2013, 11:11

 [ТС]

10

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TDM.OpenADOTables;
var
    i : integer;
    Temp : TComponent;
begin
    if ADOConn.Connected then
        for i := ComponentCount - 1 downto 0 do
        begin
            Temp := Components[i];
            if Temp is TADOTable then
            begin
                (Temp as TADOTable).Close;
                (Temp as TADOTable).Open;
            end;
        end;
end;

В том коде, что открытие карточки, я поставил проверку состояния DataSet:

Delphi
1
2
3
4
    If dsCards.DataSet.State = dsInactive Then
      ShowMessage('Close!')
    else
      ShowMessage('Open!');

Выбивает Open, то есть, как бы Dataset активен…



0



Bit_Man

478 / 391 / 112

Регистрация: 24.04.2012

Сообщений: 1,622

Записей в блоге: 3

17.07.2013, 10:03

11

Цитата
Сообщение от SashaBucheR
Посмотреть сообщение

Выбивает на строке OpenADOTables

Если так то проверяй Таблицы после открытия

Delphi
1
(Temp as TADOTable).Open;

Цитата
Сообщение от SashaBucheR
Посмотреть сообщение

выбивает при создании новой карточки

Delphi
1
DM.tblInvoiceIn.Append;

Добавлено через 3 минуты

Delphi
1
DM.tblInvoiceIn.Active

??



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 минуты
В DataSource не тот Table указал. Теперь все заработало! Спасибо!



0



I am just trying to execute the «select» sql statement using TADOQuery component, but when TADOQuery’s «Open» statement is executing I am getting following error:

Cannot perform this operation on a closed dataset... 
ADOQuery1.Active := False;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('Select * from Table1 where Column1 = <value>');
ADOQuery1.Open;

Any guess why I am getting this error ?

mjn's user avatar

mjn

36.4k28 gold badges175 silver badges378 bronze badges

asked Nov 8, 2012 at 11:21

Vishal Tiwari's user avatar

Vishal TiwariVishal Tiwari

7392 gold badges12 silver badges28 bronze badges

5

Your code looks fine.

Check if there are any event handlers (OnBeforeOpen) or master/detail datasources attached to the query. In this case a different dataset, which is still closed, could cause the error.

answered Nov 8, 2012 at 11:44

mjn's user avatar

The issue is resolved, I am using SQL Server 2008 as database.

Here «SetAppRole» was not applied on the database, after applying it, now there is no error.

user229044's user avatar

user229044

232k40 gold badges328 silver badges336 bronze badges

answered Nov 9, 2012 at 5:43

Vishal Tiwari's user avatar

Vishal TiwariVishal Tiwari

7392 gold badges12 silver badges28 bronze badges

Проблема: При нажатии на кнопку в программе появляется сообщение об ошибке.

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);

Через поиск в абд попробовал найти сотрудника. В строке поиска ввёл саба и на экране появилось предупреждение:недопустимое имя столбца саба. Я нажал ок и на экране новое предупреждение Cannot perform this operation on a closed dataset». До этого все работало хорошо. Сталкивались ли с подобным и как решали? 

1 год 9 месяцев назад

avatar

#ссылка

1 ответ

Помогла простая перезагрузка

1 год 9 месяцев назад

avatar

#ссылка

Добавить ответ

Для добавления сообщений на форуме вам необходимо зарегистрироваться и указать мобильный телефон в своем профиле (зачем?)

ЗАДАН

1 год 9 месяцев назад

По каждому вопросу/ответу можно добавлять комментарии. Комментарии предназначены для уточнения вопроса/ответа.

 
Andriy Tysh
 
(2004-05-22 10:49)
[0]

Из-за чего может вылетать ошибка в ClientDataSet: «Cannot perform this operation on a closed dataset», если учесть, что после каждого едита или инсерта корректно стоит пост? Использую грид DBGridEh.


 
Алхимик ©
 
(2004-05-22 11:01)
[1]

«Cannot perform this operation on a closed dataset»
«Не могу выполнить эту операцию на закрытом наборе данных»


 
Andriy Tysh
 
(2004-05-22 14:25)
[2]


> Алхимик ©   (22.05.04 11:01) [1]
> «Cannot perform this operation on a closed dataset»
> «Не могу выполнить эту операцию на закрытом наборе данных»

Сенкс за транслейт!
:-)
Но у меня с этим нет проблемы, а с клиентдатасетом. Он открывается на Шов формы, а закрывается на Клоус.


 
Anatoly Podgoretsky ©
 
(2004-05-22 14:35)
[3]

Из за чего угодно, но в момент выполнения операции набор данных закрыт, хочешь выполнять то сначала открой его.


 
Andriy Tysh
 
(2004-05-24 10:29)
[4]


> Anatoly Podgoretsky ©   (22.05.04 14:35) [3]
> Из за чего угодно, но в момент выполнения операции набор
> данных закрыт, хочешь выполнять то сначала открой его.

Я это прекрасно понимаю. Вот и ставлю вопрос, что может кроме меня его закрыть. Может DBGridEh, или что-то ещё. Так как я точно не закрываю!


 
Sergey13 ©
 
(2004-05-24 10:39)
[5]

2Andriy Tysh   (24.05.04 10:29) [4]
Ну повесь на ОнКлозе месадж и посмотри когда закрывается.


 
31512 ©
 
(2004-05-24 11:13)
[6]

А в каком контексте возикает такая ошибка? Можно привести кусок кода?


 
Andriy Tysh
 
(2004-05-24 11:37)
[7]

Только-что доследил где точно вылетает.
Есть одна функция, которая удалает записи по условию:
function DeleteByFilter(AClient: TDataSet; AFilter: String): Integer;
var ATmpClient: TClientDataSet;
begin
 if not AClient.Active then
   Result:=0
 else
 try
   ATmpClient:=TClientDataSet.Create(nil);
   try
     with ATmpClient do
     begin
3        PacketRecords:=0;
       CloneCursor(TClientDataSet(AClient), True);
       Filter:=AFilter;
       Filtered:=True;
       Result:=RecordCount;
       First;
       while not Eof do
         Delete;
     end;
   finally
     FreeAndNil(ATmpClient);
   end;
 except
   Result:=0;
 end;
end;

Ставлю её на поп-ап меню. Выполняю, соответственно удаляються записи, которые относятся к номеру заказа, напр., 37002.
Потом пробую добавить снова номер 37002:
Client.Append;//State dsBrowse не переходит почему в dsInsert, а остаётся тем же
Client.FieldByName("...").As...:=...;//Здесь и вылетает ошибка
...
Client.Post;

P.S.: Если не вызывать в процессе работы этой ф-ии, то всё ОК


 
31512 ©
 
(2004-05-24 11:45)
[8]

ATmpClient:=TClientDataSet.Create(nil) — Вижу

ATmpClient.Open или ATmpClient.Active := True — не вижу.


 
Andriy Tysh
 
(2004-05-24 11:49)
[9]


> 31512 ©   (24.05.04 11:45) [8]
> ATmpClient:=TClientDataSet.Create(nil) — Вижу
>
> ATmpClient.Open или ATmpClient.Active := True — не вижу.

Действительно нет. Но только-что добавил-эффекта нет. Тот же результат.


 
Vlad ©
 
(2004-05-24 11:54)
[10]


> Andriy Tysh   (24.05.04 11:49) [9]

А чего же ты хочешь, если у тебя FreeAndNil происходит ?


 
31512 ©
 
(2004-05-24 12:05)
[11]


> Andriy Tysh   (24.05.04 11:49) [9]

Равно как не установлен источник данных для ATmpClient.
Смотри внимательнее!


 
sniknik ©
 
(2004-05-24 12:10)
[12]

попробуй его закрыть, перед уничтожением. (лишним не будет)

а сам метод мне чегото не нравится, сам по другому бы сделал, без дублей.


 
31512 ©
 
(2004-05-24 12:30)
[13]

Если в AClient передаётся TClientDataSet то предлагаю написать так:

function DeleteByFilter(AClient: TDataSet; AFilter: String): Integer;
begin
with (AClient as TClientDataSet) do
begin
if not Active then Result:=0
else
try
 PacketRecords:=0;
 Filter:=AFilter;
 Filtered:=True;
 Result:=RecordCount;
 First;
 while not Eof do
   Delete; // тут пожоже надо ещё кое - что типа Next
except
  Result:=0;
end;
end;
end;

А вообще-то вместо TDataSet можно и TClientDataSet. И никаких as уже не надо.


 
Vlad ©
 
(2004-05-24 12:41)
[14]


> 31512 ©   (24.05.04 12:30) [13]


>  while not Eof do
>    Delete; // тут пожоже надо ещё кое - что типа Next

Ничего типа Next там не надо, все итак верно


 
31512 ©
 
(2004-05-24 12:48)
[15]


> Vlad ©   (24.05.04 12:41) [14]

Значит я ошибся.


 
sniknik ©
 
(2004-05-24 13:23)
[16]

попробуй так, если не пройдет значит дело не в этой процедуре

function DeleteByFilter(AClient: TDataSet; AFilter: String): Integer;
var RNo: integer;
begin
 Result:= 0;
 if not AClient.Active then Exit;

 with AClient do begin
   DisableControls;
   try
     try
       RNo:= RecNo;
       Filter:= AFilter;
       Filtered:= True;
       Result:= RecordCount;
       while not Eof do Delete;
       Filtered:= False;
       if RNo <= RecordCount then RecNo:= RNo
                             else RecNo:= RecordCount;
     except
       Result:= 0;
     end;
   finally
     Filtered:= False;
     EnableControls;
   end;
 end;
end;


 
sniknik ©
 
(2004-05-24 13:35)
[17]

заменить, чтобы на пустой не ругалось, мало ли, может последнюю удаляем

 if not isEmpty then
   if RNo <= RecordCount then RecNo:= RNo
                         else RecNo:= RecordCount;


 
Andriy Tysh
 
(2004-05-24 14:23)
[18]

Спасибо, сейчас попробую.

P.S.: Если вместо аппенд поставить инсерт — всё алес гут.


 
Andriy Tysh
 
(2004-05-24 15:57)
[19]

Лучше работает, чем моя ф-ия. Но всё же на протяжении 5 минут тестирования один раз такой же глюк произошёл. Может случайно Ещё я доследил: если после аппенд написать едит, то всё нормально.


Возможно, вам также будет интересно:

  • Ошибка cannot open output file debug permission denied
  • Ошибка cannot open hasp driver
  • Ошибка cannot open file fsgame ltx check your working
  • Ошибка cannot open file for saving
  • Ошибка cannot modify a read only dataset

  • Понравилась статья? Поделить с друзьями:
    0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии