根据表中的列构建查询

时间:2019-03-16 10:41:54

标签: sql oracle plsql

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

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列表,并且仅在存在该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,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';

请问有人对我如何做到这一点有任何想法吗?

2 个答案:

答案 0 :(得分:2)

您可以将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; 

答案 1 :(得分:-1)

如果使用的是Transact-SQL,则可能可以利用系统视图。

SELECT SCH.[name] AS [SCHEMA]
, ST.[name] AS [TABLE_NAME]
, SUM(SP.[rows]) AS [ROW_COUNT]
FROM sys.tables AS ST
INNER JOIN sys.partitions AS SP ON ST.object_id = SP.object_id
INNER JOIN sys.schemas AS SCH ON SCH.schema_id = ST.schema_id
AND SP.[index_id] IN (0, 1)
--WHERE ST.[name] LIKE '<your table name>' + '%' -- Optional
GROUP BY SCH.[name], ST.[name]