2
votes

Embarcadero® Delphi® 2010 Version 14.0.3593.25826

We are attempting to move a database from SQL Server 2000 to SQL Server 2008. I have a TClientDataSet that is loaded with a SELECT that includes a computed column, i.e., "SELECT Comp_Col = Column1 + ' ' + Column2...".

Running against an SQL Server 2000 database, I can modify the value of the column in the TClientDataSet using the following code:

ClientDataSet1.Edit();
ClientDataSet1.FieldByName('Comp_Col').ReadOnly := false;
ClientDataSet1.FieldByName('Comp_Col').Value := 'MODIFIED';
ClientDataSet1.FieldByName('Comp_Col'').ReadOnly := true;
ClientDataSet1.Post();  // <-- EXCEPTION in 2008

Running against an SQL Server 2008 database, though, I get a "Trying to modify read-only field" error when executing .Post().

I have tried also setting .ProviderFlags = '[]' for the column (in addition to .ReadOnly = false) in the above code, but still get the error. I have also tried setting .ReadOnly = false and .ProviderFlags = '[]' at design-time via the IDE, but this does not help either.

Anybody know how to set a computed column in a TClientDataSet when running against an SQL Server 2008 database?

Thanks!

* UPDATE: ANSWERED *

I discovered the problem--or at least a workaround...

I WAS setting .ReadOnly = false for the column in the TClientDataSet object. This worked with SQL Server 2000 but not with SQL Server 2008.

If I set .ReadOnly = false in for the column instead in the TADOQuery object that is serving as the provider, then I am able to set the value of the computed column in the TClientDataSet object at run-time.

Not ideal for me since this was implemented in a generic function for TClientDataSet objects (that didn't anything about the provider), but it will have to do for now.

2
I am surprised that this is allowed at all. In the old system, what did it actually DO when posted? Did it put "MOD" into Column1 and "IFIED" into Column2? I'm not surprised that the database throws a WTF back at you. - Chris Thornton
@user356740: I believe the definitions for that field in FieldDefs still has the faReadOnly in Attributes property - AlexSC
Tnx for the workaround. One point to add: ADOQuery.Field.Readonly should be set to False before opening ClientDataSet. - saastn

2 Answers

0
votes

I discovered the problem--or at least a workaround . . .

I WAS setting .ReadOnly = false for the column in the TClientDataSet object. This worked with SQL Server 2000 but not with SQL Server 2008.

If I set .ReadOnly = false for the column instead in the TADOQuery object that is serving as the provider, then I am able to set the value of the computed column in the TClientDataSet object at run-time.

Not ideal for me since this was implemented in a generic function for TClientDataSet objects (that didn't anything about the provider), but it will have to do for now.

0
votes

My experience shows that the creation of ClientDataSet fields by calling TClientDataSet.CreaeteDataSet initially without ReadOnly flags solves the problem. After opening ClientDataSet fields' ReadOnly flags can be returned to their seats for the proper functioning of data-aware controls.