oracle中如何对多张表进行动​​态选择查询?使用表名和列名作为其他表的值?

Posted

技术标签:

【中文标题】oracle中如何对多张表进行动​​态选择查询?使用表名和列名作为其他表的值?【英文标题】:How to perform a dynamic select query for multiple tables in oracle? using table name and column names as values from other table? 【发布时间】:2021-02-17 10:26:22 【问题描述】:

我有一个表,其中包含架构名称、表名、列名等列。

schema name table name column name
dbo product colour
dbo sales quantity
dbo customer order

我想执行一个操作,以获取基于列作为列名和表作为表名的记录计数

select count(colour) as count from dbo.product
select count(quantity) as count from dbo.sales
select count(order) as count from dbo.customer

您能否建议我使用 Oracle 数据库实现此目的的正确步骤。提前致谢

预期输出

count
5
50
150

【问题讨论】:

您想如何使用这些数据?我的意思是输出应该是什么,因为可能有很多表和列,但结果应该以某种方式组合它们(Oracle 中不能有多个结果集,只能通过过程参数)。 【参考方案1】:

如果您需要获取每个表的每列计数,您可以使用DBMS_XMLGEN 包使用纯 SQL 来执行此操作,它本质上是动态执行新游标。 我认为您可以调整下面的示例查询以满足您的需求(汇总计数或将它们转换为另一种格式)。

with a as (
  select
    'all_tables' as table_name, 'table_name' as column_name
  from dual
  union all
  select 'all_tables', 'tablespace_name' from dual union all
  select 'all_tab_cols', 'column_name' from dual union all
  select 'all_indexes', 'index_name' from dual union all
  select 'all_indexes', 'tablespace_name' from dual
)
select
  table_name,
  column_name,
  cast(extractvalue(
    dbms_xmlgen.getxmltype(
      'select count(' || column_name || ') as cnt' || chr(10) ||
      'from ' || table_name
    ),
    '/ROWSET/ROW/CNT'
  ) as int) as cnt
from a
表名 | COLUMN_NAME |碳纳米管 :----------- | :---------------- | ----: 所有表 |表名 | 71 所有表 |表空间名称 | 43 all_tab_cols |列名 | 20983 所有索引 |索引名称 | 81 所有索引 |表空间名称 | 73

db小提琴here

【讨论】:

【参考方案2】:

您不能在纯 sql 中执行此操作,但您可以在 pl/sql 中轻松执行此操作。在下面的代码中,我将结果存储在一个名为 rowcounts 的表中,它假设您的表和列名被调用

CREATE table mytables (schema_name VARCHAR2(100), table_name, VARCHAR2(100), column_name VARCHAR2(100));
INSERT INTO mytables (schema_name, table_name, column_name) VALUES ('dbo','product','colour');
INSERT INTO mytables (schema_name, table_name, column_name) VALUES ('dbo','sales','quantity');
INSERT INTO mytables (schema_name, table_name, column_name) VALUES ('dbo','customer','order');

CREATE TABLE rowcounts (table_name VARCHAR2(500), rowcount NUMBER);

DECLARE 
  l_rowcount INT;
BEGIN
  FOR r IN (SELECT * FROM mytables) LOOP
    EXECUTE IMMEDIATE 'SELECT COUNT('||r.column_name||') FROM '||r.table_name INTO l_rowcount;
    --dbms_output.put_line('SELECT COUNT('||r.column_name||') FROM '||r.table_name);
    INSERT INTO rowcounts(table_name, rowcount) VALUES (r.table_name, l_rowcount);
  END LOOP;
  COMMIT;
END;
/

--DROP TABLE rowcounts;

【讨论】:

以上是关于oracle中如何对多张表进行动​​态选择查询?使用表名和列名作为其他表的值?的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE怎么用SQL查询多张表和多个时间点的数据的行数?

Oracle 同时删除多张表

如何在oracle中查询每个表的记录条数

如何在oracle中查询每个表的记录条数

数据库中的视图

oracle多张表可以都用一个序列吗?