【问题标题】:How to to identify and fetch a fixed value from a fixed column across the Oracle DB 11g如何从 Oracle DB 11g 中的固定列中识别和获取固定值
【发布时间】:2021-05-17 19:34:58
【问题描述】:

您好,我需要从 DWH 模式的固定列中查找和识别特定值,理想情况下是为了识别与每个数字关联的系统名称,以便我可以跟踪与该系统关联的表的总数示例将给出清晰的理解

假设我有大约 100 个系统,从 1 到 100 个数字,所以每个系统都由一个数字定义

例子

SYSTEM NO
LOGISTIC 1
FINANCE 2
SALES 3
CREDIT 4
SECUTIRY 5

一直到 100 岁

在数据库中,我有数千个表,因此每个表都有一个名为 ETL_SOURCE_SYSTEM 的固定列,该列将定义此编号,以便有一个元数据静态表/查找表,它将保存系统名称及其关联的系统编号, 所以不是系统和系统号是唯一的

所以现在我需要提出一个动态 sql 来扫描 DWH 中的所有模式,以确定哪个系统名称和编号具有所有表中所有模式的总计数

查询

select * from dba_tab_cols
where column_name like '%ETL_SOURCE_SYSTEM%'

查询 - 新思路

select 'with tmp(schema_name,table_name, system_nbr) as (' from dual 
union all 
select 'select '''||owner||'''''as SCHEMA_NAME'','''||object_name||'''''as TABLE_NAME'',ETL_SOURCE_SYSTEM from '||object_name||' union all ' from dba_objects 
where owner not in ('EXCLUDE the some of the nor relevant schemas like SYS,PUBLIC..')
--and owner=''
and object_type ='TABLE'
union all
select 'select '''','''',0 from dual) select owner,table_name,system_nbr from tmp order by owner,system_nbr desc ;' from dual; 

如果这真的可以在动态 sql 中以从所有表中获取值系统 1 到 100 以获得以下所需结果

预期结果

SCHEMA_NAME TOTAL_COUNTS_OF_TABLES SYSTEM_NAME SYSTEM_NUMBER 
STAGE       150                    LOGISTIC    1
EDW         300                    LOGISTIC    1
MART        600                    LOGISTIC    1
STAGE       150                    FINANCE     2
EDW         300                    FINANCE     2
MART        600                    FINANCE     2
STAGE       150                    SALES       3
EDW         300                    SALES       3
MART        600                    SALES       3
STAGE       150                    CREDIT      4
EDW         300                    CREDIT      4
MART        600                    CREDIT      4

注意:DB 是 Oracle 11g,我只介绍了几个模式,例如模式列表大 50+ 或更多

有什么建议吗?

【问题讨论】:

    标签: sql oracle plsql dynamic-sql


    【解决方案1】:

    如您所料,它是动态 SQL。这是一个示例,它显示了如何做到这一点。我想你得稍微修改一下(或多一点),但原则上应该没问题。

    为简单起见,我只是将输出显示到屏幕上。如果您想以不同的方式执行此操作,例如使用会返回集合或引用的函数,请执行此操作。

    在代码中读取 cmets。

    SQL> declare
      2    l_cnt number;         -- number of tables in each schema
      3    l_tab varchar2(30);   -- one (any; I chose MAX) table in each schema, as all of them contain ETL_SOURCE_SYSTEM column
      4    l_ess number;         -- value of ETL_SOURCE_SYSTEM in L_TAB table
      5    l_sys varchar2(20);   -- system name
      6    l_out varchar2(200);  -- output string
      7  begin
      8    -- display header
      9    dbms_output.put_line('Schema      Tabs   System     ESS' ||chr(10) ||
     10                            '----------- ----   ---------- ---');
     11    -- loop through all users; I'm using only two users in my database
     12    for cur_r in (select username from dba_users
     13                  where username in ('MICHAEL', 'SCOTT')
     14                 )
     15    loop
     16      -- pick any (I chose MAX) table name and count of tables for each schema
     17      execute immediate 'select max(table_name), count(*) from dba_tables where owner = ' ||
     18        chr(39) || cur_r.username || chr(39)
     19        into l_tab, l_cnt;
     20
     21      -- fetch ETL_SOURCE_SYSTEM value in that schema
     22      execute immediate 'select etl_source_system from ' || cur_r.username ||'.'|| l_tab into l_ess;
     23
     24      -- find system name in the lookup table (located in schema I use to run this code; should
     25      -- be a privileged user which has access to DBA_ views
     26      select system
     27        into l_sys
     28        from t_lookup
     29        where etl_source_system = l_ess;
     30
     31      -- compose the output string
     32      l_out := rpad(cur_r.username, 12, ' ') || to_char(l_cnt, '990') || '   ' ||
     33               rpad(l_sys         , 10, ' ') || to_char(l_ess, '990');
     34
     35      -- display the result
     36      dbms_output.put_line(l_out);
     37
     38    end loop;
     39  end;
     40  /
    Schema      Tabs   System     ESS
    ----------- ----   ---------- ---
    SCOTT         30   LOGISTIC     1
    MICHAEL       27   FINANCE      2
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    【讨论】:

    • 非常感谢模板,问题 1) 我们为什么使用 dba_user ?我们不能使用 dba_segments2) 使用 dba_tables 与 dba_segments 有什么区别,我们可以使用segments table 代替吗?
    • 为什么要使用 DBA_SEGMENTS?用户列在 DBA_USERS 中,表列在 DBA_TABLES 中。就我而言,您可以使用您认为合适的任何东西,只要它返回您需要的结果即可。
    • 脚。错误报告 - ORA-06550:第 28 行,第 14 列:PL/SQL:ORA-00942:表或视图不存在 ORA-06550:第 26 行,第 6 列:PL/SQL:忽略 SQL 语句 06550.00000 -“行%s,列 %s:\n%s" *原因:通常是 PL/SQL 编译错误。 *行动:
    • 在脚本中我使用了 SET SERVER OUTPUT ON line 1 所以错误在 l_sys 中
    • ORA-00942 表(或视图)不存在(不是 L_SYS 局部变量)。哪一个?不能说,我没有你的数据库。如图所示,它适用于我的数据库和我的表。如果它是关于 L_SYS 和 T_LOOKUP 表的,那么这个表在你的数据库中的命名不是这样的。我不知道那张桌子的名字是什么。
    猜你喜欢
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-22
    • 2019-12-04
    • 2014-04-13
    相关资源
    最近更新 更多