I'm using TADODataSet to read data and use TDataSetProvider to transfer
data to a TClientDataSet. The problem is if the SQL statement (which I
assign to ADO dataset's CommandText property) is union of 2 select
statements like 'select field_1, field_2 from table_a where condition_1
union select field_1, field_2 from table_a where condition_2', and if I try
to edit data in the client dataset, I always get an error message like
follows:
Field 'field_1' cannot be modified
No fields in this client dataset can be edited. How can I make it editable?
Thanks for any clues.
Regards,
George
--
Bill Todd (TeamB)
> My guess is that the ReadOnly property of the field objects is true. If
> so, set it to false. You will also have to set the table name in the
> TDataSetProvider's OnGetTableName event handler.
I've tried these 2 steps exactly as you suggested, there are still
problems:
1.After I set client dataset's all fields' ReadOnly to False, I can
modify the data but I can not post it. I always get the error message as
follows:
Trying to modify read-only field
2.The code of the dataset provider's OnGetTableName event handler is as
follows:
procedure TDOModule.dspGetTableName(Sender: TObject; DataSet: TDataSet;
var TableName: String);
var
SQL: string;
nPos: Integer;
begin
if TableName <> '' then //Line 7
Exit;
//Get the underlying SQL statement used to fetch data and normalize it
SQL := ((Sender as TDataSetProvider).DataSet as
TADODataSet).CommandText;
SQL := StringReplace(SQL, #13, ' ', [rfReplaceAll]);
SQL := StringReplace(SQL, #10, ' ', [rfReplaceAll]);
SQL := UpperCase(SQL);
//If SQL statement is a union of 2 or more SELECT statements,
//use the first table name in the FROM clause of the first SELECT
statement
if AnsiPos(' UNION ', SQL) > 0 then
begin
SQL := Trim(Copy(SQL, AnsiPos(' FROM ', SQL) + 6, MaxInt));
System.Delete(SQL, AnsiPos(' ', SQL), MaxInt);
nPos := AnsiPos(',', SQL);
if nPos > 0 then
System.Delete(SQL, nPos, MaxInt);
TableName := SQL;
end;
end;
I set a break point at the beginning (on line 7) of this event handler,
but it's not trapped when I call dsp.GetRecords method (For some reasons,
I have to call this method directly instead of call client dataset's Open
method).
What can I do now?
Regards,
George
>1.After I set client dataset's all fields' ReadOnly to False, I can
you should set field properties on dsp side
> SQL := ((Sender as TDataSetProvider).DataSet as
>TADODataSet).CommandText;
better use
IProviderSupport(TDataSetProvider(Sender).DataSet).PSGetCommandText
>but it's not trapped when I call dsp.GetRecords method (For some reasons,
see Provider.pas to get the idea when this event handler is used
(ApplyUpdates not GetRecords)
--
Vladimir Ulchenko aka vavan
> On 7 May 2008 19:19:59 -0700, George Wei <nob...@yahoo.com> wrote:
>
>>1.After I set client dataset's all fields' ReadOnly to False, I can
>
> you should set field properties on dsp side
Sorry I don't know how to do what you said. Will you please explain it in
detail? Or can you give me some sample code? Thanks.
Regards,
George
>Sorry I don't know how to do what you said. Will you please explain it in
I think the simplest way would be to create persistent fields in
corresponding dataset linked to provider and set needed field
properties there. alternatively you could set field properties in say
AfterOpen event handler
Yes I do it in TADODataSet's AfterOpen event handler, then the client
dataset is editable now.
Regards,
George