Hello,
I had this need already but always could get around it with bookmarks instead. I have a query (which can be a TZReadOnlyQuery or TZQuery) with an "unknown" select query. I need to find which fields are index fields on a database level, based on which values I can find the exact same record in an other query.
There are a couple of properties under TField/TZField but they seem to be unused (always return the same value).
Any ideas? :)
Cheers!
Get index field(s) from TZAbstractRODataSet
Get index field(s) from TZAbstractRODataSet
Delphi 12.2, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
-
- Platinum Boarder
- Posts: 1962
- Joined: 17.01.2011, 14:17
Re: Get index field(s) from TZAbstractRODataSet
My first Idea was to take a look at TZColumnInfo and see where that leads. But TZColumnInfo doesn't store that kind of information.
My second guess was to take a look what the generic resolver (TZGenerateSQLCachedResolver in ZDbcGenericResolver.pas) does. The Generic Resolver doesn't look at any inernal information at all. It just searches the dataset for the first column that has a table name attached. Then it feeds the Catalog, Schema and TableName information into IZDatabaseMetadata.GetPrimaryKeys.
So - what you could do is:
- Check if all columns are from the same table
- Use GetPrimaryKeys to get the primary key of that table
- Check if all the fields in GetPrimaryKeys are available
- if not all fields of the primary key are available, you might want to check for unique indices using GetIndexInfo
My second guess was to take a look what the generic resolver (TZGenerateSQLCachedResolver in ZDbcGenericResolver.pas) does. The Generic Resolver doesn't look at any inernal information at all. It just searches the dataset for the first column that has a table name attached. Then it feeds the Catalog, Schema and TableName information into IZDatabaseMetadata.GetPrimaryKeys.
So - what you could do is:
- Check if all columns are from the same table
- Use GetPrimaryKeys to get the primary key of that table
- Check if all the fields in GetPrimaryKeys are available
- if not all fields of the primary key are available, you might want to check for unique indices using GetIndexInfo
Re: Get index field(s) from TZAbstractRODataSet
I solved my issue by imported and exported keys in the mean time which seem to be doing the trick for my purpose.
However it would be really nice if we could get TField.IsIndexField working under Zeos :)
However it would be really nice if we could get TField.IsIndexField working under Zeos :)
Delphi 12.2, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
Re: Get index field(s) from TZAbstractRODataSet
Not reliable in general... A field in a query could be taken from any table, aliased, taken from a view and so on.
-
- Platinum Boarder
- Posts: 1962
- Joined: 17.01.2011, 14:17
Re: Get index field(s) from TZAbstractRODataSet
I am not sure. Embarcadero says the following about the IsIndexField property:
Soo - translated to Zeos the IsIndexField property should be yes if the field is listed in TZQuery.SortedFields or in IndexFieldName? But then this doesn't reflect the primary key in any way?Embarcadero Delphi online help wrote:Inspect the IsIndexField to determine if a field is used in the dataset's current index.
How do you do that if the primary key of a table doesn't get used in any foreign key? Does it work then?
On the DBC layer the TZGenericResolver does exactly that. It looks for a table name and then queries for the primary key.
Re: Get index field(s) from TZAbstractRODataSet
No, not at all. In that case repositioning won't be possible (or inaccurate) but for my purpose it's not a huge deal. I'll take a look at the advices above once my new feature is completely error-free :)marsupilami wrote: ↑16.07.2023, 12:19How do you do that if the primary key of a table doesn't get used in any foreign key? Does it work then?
I'm working on a "database browser" in my tool for people who don't have knowledge about databases but still need to interact with data. You select a starting table and then "walk through" it's relations: Repositioning is needed when in-line edit is toggled as in this case I'm replacing the TZQuery object with a TZReadOnlyQuery for performance improvement. And it's nice if they end up with the same selection once I did that.
However I just recognized an other bug - I'm only repositioning to ONE record and since multi-select is allowed...
See, long way to go :D
You do not have the required permissions to view the files attached to this post.
Delphi 12.2, Zeos 8 from latest GIT snapshot
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
Using:
- MySQL server 8.0.18; libmysql.dll 8.0.40 x64 5.7.19 x68, libmariadb.dll 3.3.11
- Oracle server 11.2.0, 12.1.0, 19.0.0; oci.dll 21.15
- MSSQL 2012, 2019; sybdb.dll FreeTDS_3102
- SQLite 3.47
Re: Get index field(s) from TZAbstractRODataSet
But how it looks for table name? And how it could know when key field is aliased?marsupilami wrote: ↑16.07.2023, 12:19 On the DBC layer the TZGenericResolver does exactly that. It looks for a table name and then queries for the primary key.
Anyway there are VIEWS that could contain literally everything