2017-06-09 52 views
0

我有5個表,我想比較DLL日期和Max(ora_rowscn)。SCN_TO_TIMESTAMP(Max(ora_rowscn))爲表列表創建一個新的修改表

select owner, object_name, LAST_DDL_TIME from dba_objects; 
select * from dba_objects 
where object_name in ('Table_1', 'Table_2', 'Table_3', 'Table_4','Table_5') 

我知道我可以用一個「與條款」 &聯盟所有SCN_TO_TIMESTAMP數據加入到DBA_OBJECTS表,但有一個更有效的方式在現實中我有超過5桌。

with 
table 1 as (SELECT 'table1' as Table,SCN_TO_TIMESTAMP (Max(ora_rowscn)) from table1), 
table 2 as (SELECT 'table2' as Table,SCN_TO_TIMESTAMP (Max(ora_rowscn)) from table2), 
table 3 as (SELECT 'table3' as Table,SCN_TO_TIMESTAMP (Max(ora_rowscn)) from table3), 
....and so on 

有沒有一種方法,我可以用在DBA_OBJECTS查詢使用SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)),列表中的每個表的名稱創建的列表?

回答

0

您可以使用dbms_xmlgen.getxml()半動態生成查詢。如果我創建並填充兩個虛擬表格:

create table table_1(id number); 插入table_1值(42); create table table_2(id number); - 等待一秒鐘 插入到table_2值(42);

話,我可以得到dba_objects數據和匹配ora_rowscn價值 - 儘管作爲XML - 一重擊:

select owner, object_name, last_ddl_time, 
    dbms_xmlgen.getxml('select max(ora_rowscn) as max_ora_rowscn from ' 
    || object_name) as xml_clob 
from dba_objects 
where object_type = 'TABLE' 
and object_name in ('TABLE_1', 'TABLE_2'); 

OWNER   OBJECT_NAME   LAST_DDL_ XML_CLOB           
------------- -------------------- --------- -------------------------------------------------- 
MY_SCHEMA  TABLE_2    09-JUN-17 <?xml version="1.0"?>        
              <ROWSET>           
               <ROW>            
               <MAX_ORA_ROWSCN>10321138892740</MAX_ORA_ROWSCN> 
               </ROW>           
              </ROWSET>           

MY_SCHEMA  TABLE_1    09-JUN-17 <?xml version="1.0"?>        
              <ROWSET>           
               <ROW>            
               <MAX_ORA_ROWSCN>10321138892720</MAX_ORA_ROWSCN> 
               </ROW>           
              </ROWSET>           

這並不立即尋找一切有用的,但你可以使用更多的XML DB功能提取你想要的實際數字:

with cte as (
    select owner, object_name, last_ddl_time, 
    dbms_xmlgen.getxml('select max(ora_rowscn) as max_ora_rowscn from ' 
     || object_name) as xml_clob 
    from dba_objects 
    where object_type = 'TABLE' 
    and object_name in ('TABLE_1', 'TABLE_2') 
) 
select cte.owner, cte.object_name, 
    to_char(cte.last_ddl_time, 'YYYY-MM-DD HH24:MI:SS') as last_ddl_time, 
    x.max_ora_rowscn, 
    to_char(scn_to_timestamp(x.max_ora_rowscn), 'YYYY-MM-DD HH24:MI:SS') as max_scn_timestamp 
from cte 
cross join xmltable('/ROWSET/ROW' 
    passing xmltype(cte.xml_clob) 
    columns max_ora_rowscn number path 'MAX_ORA_ROWSCN' 
) x; 

OWNER   OBJECT_NAME   LAST_DDL_TIME  MAX_ORA_ROWSCN MAX_SCN_TIMESTAMP 
------------- -------------------- ------------------- -------------- ------------------- 
MY_SCHEMA  TABLE_1    2017-06-09 13:46:46  1.0321E+13 2017-06-09 13:46:44 
MY_SCHEMA  TABLE_2    2017-06-09 13:46:46  1.0321E+13 2017-06-09 13:46:47 

但是你有幾個問題與你在做什麼。首先注意到兩個表的DDL時間顯示爲相同,並且ora_rowscn對於table_1看起來合理;但是對於table_2它似乎在表甚至被創建之前。這關係到SCN的工作方式。

更大的問題是你limited in how far you can look back;如果表的最大值ora_rowsn超出了數據庫的重做/閃回保留期限,那麼嘗試轉換它將會失敗。

這是你在尋找可能的一切就足夠了近 - 你還沒說爲什麼你這樣做 - 你可能會選擇不嘗試轉換ora_rowscn值是太舊了,這你可以在數據字典的其他地方找到表單。這可能會讓你的整個練習毫無意義。您還可能需要處理空表,其中max(ora_rowscn)將爲空,導致scn_to_timestamp()失敗。