Overview
The FD MetaInfo Query component lets you query database metadata — tables, columns, indexes, foreign keys, stored procedures, and more — directly from a report. It wraps FireDAC’s TFDMetaInfoQuery and behaves like an FD Table: drop it on the report, set properties in the designer, then open and navigate it in script.
Unlike an FD Query, there is no SQL to write. You tell the component what kind of metadata you want using the MetaInfoKind property, optionally filter by object name or schema, then open it. The result is a read-only dataset you can iterate row by row.
Adding to a Report
Drop an FD MetaInfo Query from the designer palette onto the report alongside your FD Database component. Set the Database property to point at your connection, then configure the remaining properties in the Object Inspector before running the report.
Properties
Database
The FD Database component this query will use. Must be set before opening the dataset. If left blank, the component falls back to the default database set on the FD Components object.
MetaInfoKind
Controls what type of metadata the query returns. Set this in the designer or from script using the named constants listed below.
| Constant | Value | Returns |
|---|---|---|
mkNone | 0 | No query — dataset will be empty |
mkCatalogs | 1 | Available catalogs (databases) |
mkSchemas | 2 | Available schemas |
mkTables | 3 | Tables and views |
mkTableFields | 4 | Columns of a specific table |
mkIndexes | 5 | Indexes on a specific table |
mkIndexFields | 6 | Columns in a specific index |
mkPrimaryKey | 7 | Primary key of a specific table |
mkPrimaryKeyFields | 8 | Columns in the primary key |
mkForeignKeys | 9 | Foreign keys on a specific table |
mkForeignKeyFields | 10 | Columns in a specific foreign key |
mkPackages | 11 | Packages (Oracle) |
mkProcs | 12 | Stored procedures and functions |
mkProcArgs | 13 | Parameters of a specific procedure |
mkGenerators | 14 | Generators / sequences (Firebird) |
mkResultSetFields | 15 | Columns returned by a stored procedure |
mkTableTypeFields | 16 | Columns of a table type (Oracle) |
BaseObjectName
The name of the table, index, foreign key, or procedure you want to inspect. This property is only used for field-level and index-level kinds — it specifies which parent object to drill into. It has no effect when MetaInfoKind = mkTables or other list-level kinds.
| MetaInfoKind | BaseObjectName specifies |
|---|---|
mkTableFields | The table whose columns to return |
mkIndexes | The table whose indexes to return |
mkIndexFields | The table containing the index |
mkPrimaryKey | The table whose primary key to return |
mkPrimaryKeyFields | The table containing the primary key |
mkForeignKeys | The table whose foreign keys to return |
mkForeignKeyFields | The table containing the foreign key |
mkProcArgs | The procedure whose parameters to return |
ObjectName
A filter applied to the names of objects in the result set. Leave blank to return all objects.
| MetaInfoKind | ObjectName filters |
|---|---|
mkTables | Table names returned |
mkProcs | Procedure names returned |
mkSchemas | Schema names returned |
mkIndexFields | The index name within the table set by BaseObjectName |
mkForeignKeyFields | The foreign key name within the table set by BaseObjectName |
Note: Wildcard support in ObjectName depends entirely on the database driver. Actian Zen (Sage 50) does not reliably support % wildcards here — leave ObjectName blank and filter the results yourself in script after opening.
SchemaName
Filters results to a specific schema. Leave blank to include all schemas.
CatalogName
Filters results to a specific catalog. Leave blank to include all catalogs.
Wildcard
A secondary wildcard pattern applied to the result. Behaviour depends on the driver.
ObjectScopes
Controls which ownership scopes are included in the result. Set this from script using the helper methods below — the named constants (osMy, osOther, osSystem) are available in script only and will not appear in the designer. Leave at the default (0) to let the driver return its default scope.
| Constant | Meaning |
|---|---|
osMy | Objects owned by the current user |
osOther | Objects owned by other users |
osSystem | System objects |
TableKinds
Controls which table types are included when MetaInfoKind = mkTables. Set this from script using the helper methods below — the named constants are available in script only. Leave at the default (0) to let the driver return its default set of table types.
| Constant | Meaning |
|---|---|
tkSynonym | Synonyms |
tkTable | Base tables |
tkView | Views |
tkTempTable | Temporary tables |
tkLocalTable | Local tables |
Read-Only Properties
| Property | Type | Description |
|---|---|---|
RecordCount | Integer | Number of rows in the result |
EOF | Boolean | True when positioned past the last row |
BOF | Boolean | True when positioned before the first row |
FieldCount | Integer | Number of columns in the result |
ColumnDataTypeName | String | SQL-style type name for the current row’s COLUMN_DATATYPE value (e.g. VARCHAR, INTEGER). Only meaningful when MetaInfoKind = mkTableFields. |
Script Methods
Opening and Closing
MetaInfoQuery1.Open;
MetaInfoQuery1.Close;
You can also set Active := True and Active := False.
Navigation
MetaInfoQuery1.First;
MetaInfoQuery1.Last;
MetaInfoQuery1.Next;
MetaInfoQuery1.Prior;
Field Access
// Returns nil if field not found - safe to call on any row
F := MetaInfoQuery1.FindField('TABLE_NAME');
// Raises an exception if field not found
F := MetaInfoQuery1.FieldByName('TABLE_NAME');
ObjectScopes Helpers
Use these instead of setting ObjectScopes directly.
MetaInfoQuery1.IncludeScope(osMy);
MetaInfoQuery1.IncludeScope(osOther);
MetaInfoQuery1.ExcludeScope(osSystem);
MetaInfoQuery1.ClearScopes; // remove all scope flags
TableKinds Helpers
Use these instead of setting TableKinds directly.
MetaInfoQuery1.IncludeTableKind(tkTable);
MetaInfoQuery1.IncludeTableKind(tkView);
MetaInfoQuery1.ExcludeTableKind(tkSynonym);
MetaInfoQuery1.ClearTableKinds; // remove all kind flags
GetFieldTypeName
Converts any COLUMN_DATATYPE integer to a SQL-style type name string. Useful when you want to translate the raw value yourself rather than using the ColumnDataTypeName property.
var TypeName: String;
TypeName := MetaInfoQuery1.GetFieldTypeName(
MetaInfoQuery1.FieldByName('COLUMN_DATATYPE').AsInteger);
// returns e.g. 'VARCHAR', 'INTEGER', 'DATETIME'
EnableControls / DisableControls
MetaInfoQuery1.DisableControls;
// ... navigate many rows without UI updates ...
MetaInfoQuery1.EnableControls;
IsEmpty
if MetaInfoQuery1.IsEmpty then
ShowMessage('No metadata found');
Additional Constants
These constants are available in script for working with results from index and foreign key queries.
Index Kind (ikNonUnique, ikUnique, ikPrimaryKey)
Returned in the INDEX_TYPE field when MetaInfoKind = mkIndexes.
Cascade Rule Kind
| Constant | Meaning |
|---|---|
ckNone | No cascade action |
ckCascade | Cascade delete or update |
ckRestrict | Restrict |
ckSetNull | Set null |
ckSetDefault | Set default |
Examples
List All Tables
MetaInfoQuery1.MetaInfoKind := mkTables;
MetaInfoQuery1.IncludeScope(osMy);
MetaInfoQuery1.IncludeScope(osOther);
MetaInfoQuery1.IncludeTableKind(tkTable);
MetaInfoQuery1.IncludeTableKind(tkView);
MetaInfoQuery1.Open;
while not MetaInfoQuery1.EOF do
begin
ShowMessage(MetaInfoQuery1.FieldByName('TABLE_NAME').AsString);
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
Filter to a Specific Table Name
Use ObjectName for an exact name match where your driver supports it. For Actian Zen (Sage 50), leave ObjectName blank and filter in script instead — Zen does not reliably support wildcard filtering here.
// Exact match via ObjectName (works on most drivers)
MetaInfoQuery1.MetaInfoKind := mkTables;
MetaInfoQuery1.ObjectName := 'JRNLROW';
MetaInfoQuery1.Open;
// Script-side filtering (use this for Actian Zen / Sage 50)
MetaInfoQuery1.MetaInfoKind := mkTables;
MetaInfoQuery1.ObjectName := ''; // leave blank - return all tables
MetaInfoQuery1.Open;
while not MetaInfoQuery1.EOF do
begin
if Pos('JRNL', MetaInfoQuery1.FieldByName('TABLE_NAME').AsString) = 1 then
ShowMessage(MetaInfoQuery1.FieldByName('TABLE_NAME').AsString);
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
List Columns of a Table
MetaInfoQuery1.MetaInfoKind := mkTableFields;
MetaInfoQuery1.BaseObjectName := 'CUSTOMER';
MetaInfoQuery1.Open;
while not MetaInfoQuery1.EOF do
begin
ShowMessage(
MetaInfoQuery1.FieldByName('COLUMN_NAME').AsString + ' - ' +
MetaInfoQuery1.ColumnDataTypeName);
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
Build a Comma-Delimited Column List
var ColList: String;
MetaInfoQuery1.MetaInfoKind := mkTableFields;
MetaInfoQuery1.BaseObjectName := 'CUSTOMER';
MetaInfoQuery1.Open;
ColList := '';
while not MetaInfoQuery1.EOF do
begin
if ColList <> '' then ColList := ColList + ', ';
ColList := ColList + MetaInfoQuery1.FieldByName('COLUMN_NAME').AsString;
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
ShowMessage(ColList);
Check Whether a Column Exists
var Found: Boolean;
MetaInfoQuery1.MetaInfoKind := mkTableFields;
MetaInfoQuery1.BaseObjectName := 'CUSTOMER';
MetaInfoQuery1.Open;
Found := False;
while not MetaInfoQuery1.EOF do
begin
if MetaInfoQuery1.FieldByName('COLUMN_NAME').AsString = 'EMAIL' then
begin
Found := True;
Break;
end;
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
if Found then
ShowMessage('EMAIL column exists')
else
ShowMessage('EMAIL column not found');
List Stored Procedures
MetaInfoQuery1.MetaInfoKind := mkProcs;
MetaInfoQuery1.Open;
while not MetaInfoQuery1.EOF do
begin
ShowMessage(MetaInfoQuery1.FieldByName('OBJECT_NAME').AsString);
MetaInfoQuery1.Next;
end;
MetaInfoQuery1.Close;
Notes
The fields returned by FD MetaInfo Query vary by database driver. Common field names for mkTables include TABLE_NAME, TABLE_TYPE, and TABLE_SCHEMA. For mkTableFields the most commonly used fields are COLUMN_NAME, COLUMN_DATATYPE, COLUMN_LENGTH, COLUMN_PRECISION, COLUMN_SCALE, and COLUMN_NULLABLE.
The COLUMN_DATATYPE field contains a numeric value corresponding to a FireDAC field type. Use ColumnDataTypeName or GetFieldTypeName to convert it to a readable SQL type name.
FD MetaInfo Query is read-only. Editing, posting, or deleting rows is not supported.