这可能吗?我正在使用 ORACLE 10g。
例如:我有 50 个表,名称为 A01、A02、A03、A04.........A50。
所有这些表都有“相同的列名”例如:姓名、年龄、位置
(注意:列名称相同,但列中的值不同)。
在 END... 我想查看列中的所有数据:名称、年龄、位置来自所有以字母 A 开头的表。
(注2:所有以A开头的表格都不是静态的,它们是动态的,意味着可能发生不同的变化。例如:可以删除A01到A10,可以添加A99)。
很抱歉没有澄清。
DECLARE
TYPE CurTyp IS REF CURSOR;
v_cursor CurTyp;
v_record A01%ROWTYPE;
v_stmt_str VARCHAR2(4000);
BEGIN
for rec in (
select table_name
from user_tables
where table_name like 'A%'
) loop
if v_stmt_str is not null then
v_stmt_str := v_stmt_str || ' union all ';
end if;
v_stmt_str := v_stmt_str || 'SELECT * FROM ' || rec.table_name;
end loop;
OPEN v_cursor FOR v_stmt_str;
LOOP
FETCH v_cursor INTO v_record;
EXIT WHEN v_cursor%NOTFOUND;
-- Read values v_record.name, v_record.age, v_record.location
-- Do something with them
END LOOP;
CLOSE v_cursor;
END;
根据我的理解,如果您想查看以 A 开头的表的所有列名,请尝试以下操作
select column_name,table_name from user_tab_cols where table_name like 'A%';
如果您的要求是其他内容,请明确说明。
如果您正确理解并且表的数量是恒定的,那么您可以创建VIEW
一次
CREATE VIEW vw_all
AS
SELECT name, age, location FROM A01
UNION ALL
SELECT name, age, location FROM A01
UNION ALL
...
SELECT name, age, location FROM A50
UNION ALL
然后使用它
SELECT *
FROM vw_all
WHERE age < 35
ORDER BY name
这将返回您需要的所有表格:
select table_name
from user_tables
where table_name like 'A__';
由此,您可以将动态 sql 语句构建为:
select listagg('select * from '||table_name,' union all ') within group(order by table_name)
from user_tables
where table_name like 'A__'
这实际上返回一个包含所有表和联合的 SQL 语句:
select * from A01 union all select * from A02 union all select * from A03
最后通过本机动态 sql 执行。您可以在 PL/SQL 中执行此操作,因此您需要一个函数:
create function getA
query varchar2(32000);
begin
select listagg('select * from '||table_name,' union all ') within group(order by table_name)
into query
from user_tables
where table_name like 'A__';
open res for query;
return res;
end;
请注意,您手动执行的操作基本上称为partitioning,Oracle 已经为此提供了超强的支持。即,您可以拥有看起来像超级大表的东西,但从技术上讲,它存储为一组较小的表(和较小的索引),按分区标准进行拆分。例如,如果您有数百万条支付记录,您可以按年份对其进行分区,这样一个物理表只包含一组合理的数据。尽管如此,您仍然可以在其中自由选择,如果您从其他分区访问数据,Oracle 会负责将这些数据拉入。