Subject | IBobjects 3.6, calculated fields to make a unique primary key on Joined result data sets. |
---|---|
Author | Warren Postma |
Post date | 2001-08-25T19:34:26Z |
Hello all. I have been happily using the IBObjects 3.6 for about six months
on a medium sized database project. I am now coming down to a persistent
pesky issue, using IBO's TDataset-descendants and then navigating them using
my nice Grid component, ExpressGrid from Developer Express.
In particular, I needed to add a calculated field to the TIBOQuery object,
which then causes problems, when TIBODataset.Locate methods are invoked, so
that I can locate a particular record by its record number.
I am getting an exception. Here is my call stack, and the function where it
happens.
TIB_Row.ByName('RECID')
TIB_Row.GetColumnList($E31DB8,'RECID')
TIB_Dataset.GetBufferFieldList($E31DB8,'RECID')
TIB_BDataset.SysLocateRecord('RECID',5,[],True,False,1,2147483647)
TIB_BDataset.LocateRecord('RECID',5,[],True,False)
TIBODataset.LocateRecord('RECID',5,[],True,False)
TIBODataset.Locate('RECID',5,[])
function TIB_Row.ByName( const AFieldName: string ): TIB_Column;
begin
if not GetByName( AFieldName, Result ) then
raise EIB_StatementError.Create( Format( E_FIELDNAME_NOT_FOUND,
[AFieldName] ));
end;
Basically, it appears that GetByName doesn't find the field name 'RECID',
which is in the list of Calculated fields, and exists as a Component, but is
not a column name from the SQL query itself, because it's only a Calculated
field. It appears GetByName is not checking for Calculated fields.
Note that the thing that trips this all off, the call to TIBODataset.Locate
call happens inside a data aware control that is not of my own design, which
I am using because it has very nice Outlook-2000 like grouping qualities,
but to make grouping work, it needs to locate each row in the TDataset by a
single primary key field, and does not appear to have an option to use
Bookmarks instead as the primary key. Kind of ugly, but it's what they did.
So my application was find until I added a Calculated field to my TIBOQuery
object, which I named IBO_QCATALOG. It queries a table called CATALOG. I
added a calculated integer field ( IBO_QCATALOGRECID:TIntegerField,
FieldKind=fkCalculated) that takes the IBO_QCATALOG.RecNo and makes it a
visible field because the query joins several tables, and therefore there is
no single field in the table that can function as a Unique Key, something
which a data aware control I am using (the ExpressGrid component, TdxDBGrid)
expects you to provide, if you are going to use all its advanced features.
So, is using Locate methods to locate by a Calculated Field supported in
TIBOQuery in IBO version 3.6? Can anyone suggest an approach I could
take here? Will my options change if I upgrade immediately to 4.0? My
program is nearly finished, so I hate to upgrade when everything else
working. Is there a workaround in 3.6?
---- FEATURE SUGGESTION:
Something that would be handy for me is a feature in IBOBjects to massage
the internal TBookmark data into an Ascii string (perhaps encode the data in
the bookmark into a hex string). This would allow you to Get and then
Locate on a pseudo-FIELD named '_BOOKMARK', which should be very fast.
Basically TIBODataset.Locate would need to treat '_BOOKMARK' as a special
case, and various TIBODataset methods that get a field by value should allow
yout specify '_BOOKMARK' as a magic field name. This sure would allow me to
work in a lot of Data Aware controls in a lot nicer way than I currently can
when I'm browsing Joined result sets that have no intrinsic primary key in
the result set.
Warren Postma
Next Generation Systems
on a medium sized database project. I am now coming down to a persistent
pesky issue, using IBO's TDataset-descendants and then navigating them using
my nice Grid component, ExpressGrid from Developer Express.
In particular, I needed to add a calculated field to the TIBOQuery object,
which then causes problems, when TIBODataset.Locate methods are invoked, so
that I can locate a particular record by its record number.
I am getting an exception. Here is my call stack, and the function where it
happens.
TIB_Row.ByName('RECID')
TIB_Row.GetColumnList($E31DB8,'RECID')
TIB_Dataset.GetBufferFieldList($E31DB8,'RECID')
TIB_BDataset.SysLocateRecord('RECID',5,[],True,False,1,2147483647)
TIB_BDataset.LocateRecord('RECID',5,[],True,False)
TIBODataset.LocateRecord('RECID',5,[],True,False)
TIBODataset.Locate('RECID',5,[])
function TIB_Row.ByName( const AFieldName: string ): TIB_Column;
begin
if not GetByName( AFieldName, Result ) then
raise EIB_StatementError.Create( Format( E_FIELDNAME_NOT_FOUND,
[AFieldName] ));
end;
Basically, it appears that GetByName doesn't find the field name 'RECID',
which is in the list of Calculated fields, and exists as a Component, but is
not a column name from the SQL query itself, because it's only a Calculated
field. It appears GetByName is not checking for Calculated fields.
Note that the thing that trips this all off, the call to TIBODataset.Locate
call happens inside a data aware control that is not of my own design, which
I am using because it has very nice Outlook-2000 like grouping qualities,
but to make grouping work, it needs to locate each row in the TDataset by a
single primary key field, and does not appear to have an option to use
Bookmarks instead as the primary key. Kind of ugly, but it's what they did.
So my application was find until I added a Calculated field to my TIBOQuery
object, which I named IBO_QCATALOG. It queries a table called CATALOG. I
added a calculated integer field ( IBO_QCATALOGRECID:TIntegerField,
FieldKind=fkCalculated) that takes the IBO_QCATALOG.RecNo and makes it a
visible field because the query joins several tables, and therefore there is
no single field in the table that can function as a Unique Key, something
which a data aware control I am using (the ExpressGrid component, TdxDBGrid)
expects you to provide, if you are going to use all its advanced features.
So, is using Locate methods to locate by a Calculated Field supported in
TIBOQuery in IBO version 3.6? Can anyone suggest an approach I could
take here? Will my options change if I upgrade immediately to 4.0? My
program is nearly finished, so I hate to upgrade when everything else
working. Is there a workaround in 3.6?
---- FEATURE SUGGESTION:
Something that would be handy for me is a feature in IBOBjects to massage
the internal TBookmark data into an Ascii string (perhaps encode the data in
the bookmark into a hex string). This would allow you to Get and then
Locate on a pseudo-FIELD named '_BOOKMARK', which should be very fast.
Basically TIBODataset.Locate would need to treat '_BOOKMARK' as a special
case, and various TIBODataset methods that get a field by value should allow
yout specify '_BOOKMARK' as a magic field name. This sure would allow me to
work in a lot of Data Aware controls in a lot nicer way than I currently can
when I'm browsing Joined result sets that have no intrinsic primary key in
the result set.
Warren Postma
Next Generation Systems