Board index » delphi » Cannot perform this operation on a closed dataset

Cannot perform this operation on a closed dataset


2004-05-26 04:46:40 AM
delphi102
I am trying to establish a very simple master/detail relationship in Delphi 7 connected to a IB6 OS server.
The components are active and display the correct data for record 1 in the IDE, but the application fails with the following
error when you try to run:
EDatabase exception in project1.exe with message 'Cannot preform this operation on a closed dataset.'
Here are the details:
Two units- one form, one data module, the form does 'use' the data module.
The data module has:
SQLConnection1
SQLConnection1.Connected = True
SQLDataSet1
SQLDataSet1.SQLConnection = SQLConnection1
SQLDataSet1.CommandType = ctTable // This needs to become a query, it is table now for simplicity only
SQLDataSet1.CommandText = D_CLIENT_HEADERS
SQLDataSet1.Active = True
DataSetProvider1
DataSetProvider1.DataSet = SQLDataSet1
ClientDataSet1
ClientDataSet1.ProviderName = DataSetProvider1
ClientDataSet1.Active = True
DataSource1
DataSource1.DataSet = ClientDataSet1
The FORM has three DBEdit Fields connected to DataSource1, the form correctly displays the data in record 1 of the table
D_CLIENT_HEADERS
The FORM also has a DBNavigatior connected to DataSource1
The data module ALSO has:
DataSource2
DataSource2.DataSet = SQLDataSet1
SQLDataSet2
SQLDataSet1.SQLConnection = SQLConnection1
SQLDataSet2.CommandType = ctQuery
SQLDataSet2.CommandText = SELECT * FROM DX_CLIENTTYPES
WHERE "ClientID" = :ClientID ;
SQLDataSet2.DataSource = DataSource2 // To provide parameter values
SQLDataSet2.Active = True
DataSetProvider2
DataSetProvider2.DataSet = SQLDataSet2
ClientDataSet2
ClientDataSet2.ProviderName = DataSetProvider2
ClientDataSet2.Active = True
DataSource3
DataSource3.DataSet = ClientDataSet2
The FORM has a DBGrid connected to DataSource3, with fields from DX_CLIENTTYPES. the form correctly displays the data from
DX_CLIENTTYPES for only the ClientID showing in the DBEDit fields.
According to my understanding of the documentation and tutorials I have seen, the DBGrid should auto-update as the Master record
is changed using the DBNavigatior.
Instead the application fails several seconds after trying to run it with the error message above.
'ClientID' is the exact field name of a field avalable in SQLDataSet1, as required by the documentation. It is one of the master
record values displayed on the form.
WHAT AM I MISSING? This is fundamental Delphi 101!
HELP!
Ross Wise
WEAVE, Inc.
Sacramento, CA
I'm going to go eat a whole pizza now.
 
 

Re:Cannot perform this operation on a closed dataset

Bill Todd (TeamB) writes:
Quote
>DataSource2
>DataSource2.DataSet = SQLDataSet1
>
>SQLDataSet2
>SQLDataSet1.SQLConnection = SQLConnection1
>SQLDataSet2.CommandType = ctQuery
>SQLDataSet2.CommandText = SELECT * FROM DX_CLIENTTYPES
>WHERE "ClientID" = :ClientID ;
>
>SQLDataSet2.DataSource = DataSource2 // To provide parameter values
>SQLDataSet2.Active = True


When the detail dataset is linked back to the master through its
DataSource property the detail dataset will be embedded in the master
as a nested dataset field.
OK, It works.
Question: Why is the Nested Dataset Field (named SQLDataSet2) showing up in ClientDataSet1 and not in SQLDataSet1
if it is 'embedded in the master' and DataSource2 is pointing back at SQLDataSet1?
Could DataSource2 be pointing to ClientDataSet1 instead of SQLDataSet1?
Quote

>
>DataSetProvider2
>DataSetProvider2.DataSet = SQLDataSet2


Delete DataSetProvider2. You do not need it.

>ClientDataSet2
>ClientDataSet2.ProviderName = DataSetProvider2

Do not set the ProviderName property. Instead, instantiate the field
objects of ClientDataSet1 at design time using the Fields Editor. The
last field should be the nested dataset field.

Set the DataSetFieldProperty of ClientDataSet2 to the nested dataset
field in ClientDataSet1.

>ClientDataSet2.Active = True
>
>DataSource3
>DataSource3.DataSet = ClientDataSet2



--
Bill (TeamB)
(TeamB cannot respond to questions received via email)
 

Re:Cannot perform this operation on a closed dataset

OK, I was able to set up a relationship between a master (Clients) and details (ClientTypes) that worked perfectly.
Thank you very much for your help.
Then when I tried to create a second relationship (Clients and PhoneNumbers) it did not work.
The best result I got was a working application that never updated the PhoneNumber grid while correctly updating the Client
fields and ClientTypes Grid. The more common result was the old 'Not on a closed dataset' error again.
Am I correct in assuming that I should be able to add an additional SQLDataSet3 with the query:
SQLDataSet3.CommandType = ctQuery
SQLDataSet3.CommandText = SELECT * FROM DX_PHONE_NUMBERS
WHERE "ClientID" = :ClientID ;
SQLDataSet3.DataSource = DataSource2 // To provide parameter values
SQLDataSet3.Active = True
Adding this component DID cause an additional nested DataSet field in ClientDataSet1. I then created:
ClientDataSet3
ClientDataSet3.DataSetField = ClientDataSet1SQLDataSet3
ClientDataSet3.Active = True
DataSource4
DataSource4.DataSet = ClientDataSet3
The columns of the Telephone Number Grid were automatically generated when its DataSource was set to DataSource4 just as
expected. But not data appeared either at design-time nor at run-time.
I tried using a new DataSource(5) in SQLDataSet3 instead of using DataSource2 twice, that just made things worse.
Am I way off base again? Time for another pizza?
Thanks in Advance!
Ross Wise
WEAVE, Inc.
Sacramento, CA
Bill Todd (TeamB) writes:
Quote
>DataSource2
>DataSource2.DataSet = SQLDataSet1
>
>SQLDataSet2
>SQLDataSet1.SQLConnection = SQLConnection1
>SQLDataSet2.CommandType = ctQuery
>SQLDataSet2.CommandText = SELECT * FROM DX_CLIENTTYPES
>WHERE "ClientID" = :ClientID ;
>
>SQLDataSet2.DataSource = DataSource2 // To provide parameter values
>SQLDataSet2.Active = True


When the detail dataset is linked back to the master through its
DataSource property the detail dataset will be embedded in the master
as a nested dataset field.

>
>DataSetProvider2
>DataSetProvider2.DataSet = SQLDataSet2


Delete DataSetProvider2. You do not need it.

>ClientDataSet2
>ClientDataSet2.ProviderName = DataSetProvider2

Do not set the ProviderName property. Instead, instantiate the field
objects of ClientDataSet1 at design time using the Fields Editor. The
last field should be the nested dataset field.

Set the DataSetFieldProperty of ClientDataSet2 to the nested dataset
field in ClientDataSet1.

>ClientDataSet2.Active = True
>
>DataSource3
>DataSource3.DataSet = ClientDataSet2



--
Bill (TeamB)
(TeamB cannot respond to questions received via email)