You could use a variation on an XML magic trick, by using dbms_xmlgen
to get all the values into XML documents based on a query against user_tab_columns
:
select dbms_xmlgen.getxmltype(
'select "' || column_name || '" from "' || table_name || '"')
from user_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER';
... where I'm assuming FID
is expected to be a numeric ID, so limiting only to numeric columns (and also allowing for mixed case/quoted identifiers for table and columns names, just in case). That gives one row per table, with an XML document listing the FID values in that table.
Then from that XML you can extract the individual values, again as numbers:
with cte (xml) as (
select dbms_xmlgen.getxmltype(
'select "' || column_name || '" as fid from "' || table_name || '"')
from user_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER'
)
select x.fid
from cte
cross apply xmltable(
'/ROWSET/ROW'
passing cte.xml
columns fid number path 'FID'
) x;
Or if you want to see the table/column each value came from, just include those in the CTE and select list:
with cte (table_name, column_name, xml) as (
select table_name, column_name, dbms_xmlgen.getxmltype(
'select "' || column_name || '" as fid from "' || table_name || '"')
from user_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER'
)
select cte.table_name, cte.column_name, x.fid
from cte
cross apply xmltable(
'/ROWSET/ROW'
passing cte.xml
columns fid number path 'FID'
) x;
If you want to search other schemas, then use all_tab_columns
instead, and optionally include each table's owner:
with cte (owner, table_name, column_name, xml) as (
select owner, table_name, column_name, dbms_xmlgen.getxmltype(
'select "' || column_name || '" as fid from "' || owner || '"."' || table_name || '"')
from all_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER'
)
select cte.owner, cte.table_name, cte.column_name, x.fid
from cte
cross apply xmltable(
'/ROWSET/ROW'
passing cte.xml
columns fid number path 'FID'
) x;
db<>fiddle
The basis for this trick goes back to at least 2007 but may be even older, from before getxmltype()
existed (it seems to have been added in 10g); I'd originally used xmltype(getxml())
:
select xmltype(dbms_xmlgen.getxml(
'select "' || column_name || '" from "' || table_name || '"'))
from user_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER';
which works most of the time, but if any of the tables are empty throws "ORA-06502: PL/SQL: numeric or value error".