首页 > 解决方案 > 从表中的列构建查询

问题描述

我有一个包含许多列的本地表。其中一些列是满的,一些是空的。它们由其他表上的元数据组成,例如:

SCHEMA TABLE_NAME DRIVER_TABLE JOIN_COND_1 JOIN_COND_2

以下是一些虚拟数据的示例:

SCHEMA TABLE_NAME DRIVER_TABLE JOIN_COND_1 JOIN_COND_2
BOB    TRUCKS     NULL         NULL        NULL
BOB    VANS       USER.XXX     A.ID=B.ID   NULL
BOB    CARS       USER.XXX     A.ID=B.ID   B.END_DTE >= '01-DEC-2018'

该表存在的原因是创建一种方法来计算另一个数据库中的行数。

我需要想出一种方法来使用表格获得如下输出:

SCHEMA TABLE_NAME COUNT
BOB    TRUCKS     878908
BOB    VANS       7899
BOB    CARS       876

元数据表将是查询的来源,但查询应该在一个代码块中。我不知道从哪里开始。

驱动程序表是用于限制计数的 id 列表,并且仅在存在时使用。

因此,第一行没有列出“驱动程序表”,只是一个 NULL 将是:

Select SCHEMA, TABLE_NAME, count(*) COUNT from METADATA;

第二个查询必须使用驱动表并加入:

Select SCHEMA, TABLE_NAME, count(*) COUNT from METADATA A, USER.XXX B
WHERE A.ID=B.ID;

第三个查询是:

Select SCHEMA, TABLE_NAME, count(*) COUNT from METADATA A, USER.XXX B
WHERE A.ID=B.ID
AND B.END_DTE >= '01-DEC-2018';

因此,所有这些 sql 都是从元数据列中的内容构建的。

我曾考虑过某种基于循环的组,以将列转换为变量,然后形成一个 if、then、else 逻辑。

DECLARE
l_sql_1    VARCHAR2(100);
l_sql_2    VARCHAR2(100);
l_sql_3    VARCHAR2(100);
l_sql_4    VARCHAR2(100);


BEGIN
l_sql_1 := 'SELECT SCHEMA||'.'||TABLE_NAME FROM METADATA';
l_sql_2 := 'SELECT DRIVER_TABLE FROM METADATA';
l_sql_3 := 'SELECT JOIN_COND_1 FROM METADATA';
l_sql_4 := 'SELECT JOIN_COND_2  FROM METADATA';

有没有人对我如何做到这一点有任何想法?

标签: sqloracleplsql

解决方案


您可以dynamic sql用作

SQL> set serveroutput on;
SQL> declare
 v_sql    varchar2(4000);
 v_schema varchar2(40);
 v_table  varchar2(40); 
 v_count  pls_integer;
begin
  dbms_output.put_line('schema  table   count');                       
  dbms_output.put_line('------  -----   -----');
 for c in ( select * from metadata )
 loop
   v_schema := c.schema;
   v_table  := c.table_name;
   v_sql := 'select count(*) from '||c.table_name||' a ';
  if c.driver_table is not null then
   v_sql := v_sql ||' join '||c.driver_table||' b on a.id=b.id ';
    if c.join_cond_2 is not null then
     v_sql := v_sql ||' where '||c.join_cond_2;     
    end if;   
  end if;
  execute immediate v_sql into v_count;
  dbms_output.put_line(v_schema||'     '||v_table||'    '||v_count);
 end loop;   
end; 

推荐阅读