繁体   English   中英

如何从数据库中的每个表中读取相同的列?

[英]How to read the same column from every table in a database?

我有一个包含 400 多个表的庞大数据库。 每个表的主键和“timestamp_modify”都具有相同的列id ,其中表的最后一次更改完成。

所以我想要的是两件事:

现在我想要按 ID 和表名列出所有更改的列表,例如:

Table  | id   | timestamp_modiy
Kid    | 1    | 24.10.2021 00:01
Parent | 1000 | 24.10.2021 00:02

我能想出的唯一非常糟糕的方法是,我创建一个视图,在其中手动包含每个该死的表并读出值...

有没有更好的办法?

是的,唯一的方法是union all所有表,例如:

select id, timestamp_modify
from kid
union all
select id, timestamp_modify
from parent
union all
...

性能会很糟糕,因为每次都会扫描所有表:(

我想你可能会重新考虑你的数据库设计......

您可以为此构建一个procedure ,但即便如此,它也会对性能产生一些影响。 尽管有一个循环,但使用 SQL Dynamic,您可能只需要 400 次迭代,并且在每次迭代中您都将插入该表的所有 id。

我正在做一些假设

  • 您需要每个表的所有IDs及其对应的timestamp_modify
  • 我创建了一个表来存储结果。 如果您始终以相同的名称使用它,它将回收该对象。 如果没有,您可以保留历史记录
  • 我假设每个 ID 只有一个timestamp_modify
  • 我只过滤包含两列的架构表。
  • 该表还包含 table_name,您可以识别记录的来源。

一个例子

create or replace procedure pr_build_output ( p_tmp_table in varchar2 default 'TMP_RESULT' ) 
is
vcounter   pls_integer;
vsql       clob; 
vtimestamp date; -- or timestamp 
begin 
-- create table to store results 
 select count(*) into vcounter from all_tables where table_name = upper(p_tmp_table) and owner = 'MY_SCHEMA';
 if vcounter = 1 
 then 
    execute immediate ' drop table '||p_tmp_table||' purge ' ;
 end if;
 vsql := ' create table '||p_tmp_table||' 
              ( table_name varchar2(128) , 
                id number, 
                timestamp_modify date -- or timestamp
               ) ';
 execute immediate vsql ;

-- Populate rows

for h in 
( select a.table_name from all_tables a 
  where a.owner = 'MY_SCHEMA'
  and a.table_name in ( select distinct b.table_name from all_tab_columns b where b.owner = 'MY_SCHEMA'
                        and b.column_name = 'ID' and b.column_name = 'TIMESTAMP_MODIFY'  
                      )
) 
 loop 
    vsql := ' insert into '||p_tmp_table||' ( table_name , id, timestamp_modify ) 
              select '''||h.table_name||''' as table_name , id , timestamp_modify 
              from my_schema.'||h.table_name||' 
            ' ;
    execute immediate vsql ;
    commit ;
 end loop;
 exception when others then raise;
end;
/

流水线函数怎么样?

只需设置日期时间格式(您不必这样做):

SQL> alter session set nls_date_format = 'dd.mm.yyyy hh24:mi:ss';

Session altered.

类型:

SQL> create or replace type t_row as object
  2    (table_name       varchar2(30),
  3     id               number,
  4     timestamp_modify date)
  5  /

Type created.

SQL> create or replace type t_tab is table of t_row;
  2  /

Type created.

功能:查询user_tab_columns ,其游标FOR循环获取包含IDTIMESTAMP_MODIFY列的表,动态创建select语句以返回最后一个( MAX函数,以避免too_many_rows )列的最后一个TIMESTAMP_MODIFY值(由子查询返回)的值。

SQL> create or replace function f_test
  2    return t_tab pipelined
  3  as
  4    l_str              varchar2(500);
  5    l_id               number;
  6    l_timestamp_modify date;
  7  begin
  8    for cur_r in (select table_name from user_tab_columns
  9                  where column_name = 'ID'
 10                  intersect
 11                  select table_name from user_tab_columns
 12                  where column_name = 'TIMESTAMP_MODIFY'
 13                 )
 14    loop
 15      l_str := 'select max(a.id) id, max(a.timestamp_modify) timestamp_modify ' ||
 16               'from ' || cur_r.table_name   || ' a ' ||
 17               'where a.timestamp_modify = ' ||
 18               '  (select max(b.timestamp_modify) '   ||
 19               '   from ' || cur_r.table_name         || ' b ' ||
 20               '   where b.id = a.id)';
 21      execute immediate l_str into l_id, l_timestamp_modify;
 22      pipe row(t_row(cur_r.table_name, l_id, l_timestamp_modify));
 23    end loop;
 24  end;
 25  /

Function created.

测试:

SQL> select * from table(f_test);

TABLE_NAME                             ID TIMESTAMP_MODIFY
------------------------------ ---------- -------------------
TABA                                    1 24.10.2021 14:59:29
TAB_1                                   1 24.10.2021 15:03:16
TAB_2                                  25 24.10.2021 15:03:36
TEST                                    5 24.10.2021 15:04:24

SQL>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM