(我認為對于這里的大多數用戶來說,這可能是一個簡單的問題..)
簡短描述:我需要一種方法(也許使用我不知道的 PL/SQL ..)來“從包含此類資料的所有表中選擇定義的資料”
詳細說明(示例):我有不同數量的不同表。其中一個經常變化的部分——我不知道編號和名稱——包含“FID”列。現在我需要兩個步驟:a) 選擇包含“FID”列的所有表。(我知道如何以單步方式執行此操作) b) 從所有找到的表中選擇值 FID 并顯示它。
對我來說,問題是從 a) 到 b) 的步驟。對于已知的表,我會使用 UNION,但是對于表的動態結果,我不知道 ..
uj5u.com熱心網友回復:
您可以使用XML 魔術的變體,通過使用dbms_xmlgen基于對以下內容的查詢將所有值獲取到 XML 檔案中user_tab_columns:
select xmltype(dbms_xmlgen.getxml(
'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 xmltype(dbms_xmlgen.getxml(
'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, xmltype(dbms_xmlgen.getxml(
'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, xmltype(dbms_xmlgen.getxml(
'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;
資料庫<>小提琴
uj5u.com熱心網友回復:
如果你想使用 pl/sql 我真的很喜歡流水線函式:
create type result_type as Object ( text varchar2(2000) );
create type result_type_table as table of result_type;
create or replace function select_all( p_column_name in varchar2 )
return result_type_table
deterministic
pipelined
as
v_table_name varchar2(40);
v_result result_type := result_type('');
v_table_name_cursor sys_refcursor;
v_inner_cursor sys_refcursor;
begin
open v_table_name_cursor
for 'select a.table_name
from user_tab_cols a
, user_tables b
where a.column_name = :1
and a.table_name = b.table_name'
using upper(p_column_name);
loop
fetch v_table_name_cursor into v_table_name;
exit when v_table_name_cursor%notfound;
open v_inner_cursor
for 'select '||p_column_name||' from '||v_table_name;
loop
fetch v_inner_cursor into v_result.text;
exit when v_inner_cursor%notfound;
pipe row (v_result );
end loop;
close v_inner_cursor;
end loop;
close v_table_name_cursor;
end;
/
使用這個函式很簡單:
select * from table( select_all('your_column_name') );
資料庫<>小提琴
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/356368.html
