您可以使用an XML magic trick 的变体,通过使用dbms_xmlgen 根据对user_tab_columns 的查询将所有值放入XML 文档中:
select dbms_xmlgen.getxmltype(
'select "' || column_name || '" from "' || table_name || '"')
from user_tab_columns
where upper(column_name) = 'FID'
and data_type = 'NUMBER';
... 我假设 FID 应该是数字 ID,因此仅限于数字列(并且还允许表和列名称的混合大小写/引号标识符,以防万一)。这为每个表提供了一行,其中一个 XML 文档列出了该表中的 FID 值。
然后,您可以从该 XML 中提取单个值,再次作为数字:
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;
或者,如果您想查看每个值来自的表/列,只需将它们包含在 CTE 中并选择列表:
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;
如果您想搜索其他架构,请改用all_tab_columns,并可选择包含每个表的所有者:
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
这个技巧的基础可以追溯到to at least 2007,但可能更早,早于getxmltype() 存在(它似乎已在10g 中添加);我最初使用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';
其中works most of the time,但如果任何表为空throws "ORA-06502: PL/SQL: numeric or value error"。