SCN_TO_TIMESTAMP (Max(ora_rowscn)) 为表列表创建一个新的修改表

Posted

技术标签:

【中文标题】SCN_TO_TIMESTAMP (Max(ora_rowscn)) 为表列表创建一个新的修改表【英文标题】:SCN_TO_TIMESTAMP (Max(ora_rowscn)) to create a new modified table for a list of tables 【发布时间】:2017-06-09 11:08:37 【问题描述】:

我有 5 个表,我想将 DLL 日期与 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')

我知道我可以使用“with 子句”并将所有 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))?

【问题讨论】:

【参考方案1】:

您可以使用dbms_xmlgen.getxml() 半动态地生成查询。如果我创建并填充两个虚拟表:

创建表table_1(id号); 插入 table_1 值(42); 创建表table_2(id号); -- 等待一秒钟 插入 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() 失败。

【讨论】:

以上是关于SCN_TO_TIMESTAMP (Max(ora_rowscn)) 为表列表创建一个新的修改表的主要内容,如果未能解决你的问题,请参考以下文章

[oracle]查询一个表中数据的插入时间

ORACLE 8i 遇到报错:ORA-01631: max # extents (505) reached in table

SGA_MAX_SIZE设置过大,超过MEMORY_TARGET值,数据库无法启动,导致ora-00844和ora-00851错误

ORACLE数据库修改sga_max_size和sga_target后重启报ORA-00821错

java.sql.SQLSyntaxErrorException: ORA-00907: 缺失右括号

ORA-01555 When Max Query Length Is Less Than Undo Retention, small or 0 Seconds (Doc ID 1131474.1)(示