sql查询以获取在sysdate上更新的模式中的所有表

时间:2014-02-21 12:05:35

标签: sql oracle

需要编写一个sql查询来获取模式中的所有表 已在sysdate上更新。

select  distinct(table_name)
from All_Tab_Columns 
where owner = 'DBO' 
      and last_analyzed = sysdate;

它似乎无法正常工作。

4 个答案:

答案 0 :(得分:3)

您需要在TRUNClast_analyzed上应用sysdate功能,然后才能运作

select  distinct(table_name)
from All_Tab_Columns 
where owner = 'DBO' 
      and trunc(last_analyzed) = trunc(sysdate);

答案 1 :(得分:1)

正如我在链接的问题的答案中所提到的,您可以使用ORA_ROWSCN伪列来了解上次更新表的时间。这将示例模式中的所有表,并列出根据ORA_ROWSCN在指定日期修改的表。当然,这可能需要一段时间才能运行。

set serveroutput on
declare
  last_update varchar2(10);
  bad_scn exception;
  no_scn exception;
  pragma exception_init(bad_scn, -8181);
  pragma exception_init(no_scn, -1405);
begin
  for r in (select table_name from all_tables where owner = 'DBO') loop
    begin
      execute immediate 'select to_char(scn_to_timestamp(max(ora_rowscn)), '
          || '''YYYY-MM-DD'') from DBO.' || r.table_name
        into last_update;
      if last_update = '2014-02-21' then
        dbms_output.put_line(r.table_name || ' last updated on ' || last_update);
      end if;
    exception
      when bad_scn then
        dbms_output.put_line(r.table_name || ' - bad scn');
      when no_scn then
        dbms_output.put_line(r.table_name || ' - no scn');
    end;
  end loop;
end;
/

异常处理程序覆盖视图(列出但没有SCN),并且由于某种原因存在无效的SCN;你可能想忽略它们而不是显示它们。

如果您只是寻找今天而不是特定日期,那么这可能会更快:

declare
  start_scn number;
  changed_rows number;
  changed_tables number := 0;
begin
  start_scn := timestamp_to_scn(trunc(systimestamp));
  for r in (select table_name from all_tables where owner = 'BDO'
      order by table_name) loop
    execute immediate 'select count(*) from ('
        || 'select ora_rowscn from BDO.' || r.table_name
        || ') where ora_rowscn >= :1 and rownum < 2'
      into changed_rows
      using start_scn;
    if changed_rows > 0 then
      dbms_output.put_line(r.table_name || ' updated');
      changed_tables := changed_tables + 1;
    end if;
  end loop;
  dbms_output.put_line(changed_tables || ' tables updated today');
end;
/

你可以为任何日期做同样的事情,但你需要找到当天最早和最新的SCN(这对于当前日期来说更复杂)。另请注意,这可能仅适用于您的闪回窗口 - 如果您回到远处,您将无法将SCN转换为时间戳。

答案 2 :(得分:0)

没有简单的方法可以做到这一点。你必须逐桌操作。然后在每个表上执行此查询:

select max(SCN_TO_TIMESTAMP(ORA_ROWSCN)) from <table_name>;

ORA_ROWSCN是Oracle虚拟伪列,它存储在块级别。它包含最后一个事务的“序列号”,它修改了数据库块。

函数SCN_TO_TIMESTAMP将其转换为人类可读日期数据类型。

答案 3 :(得分:-1)

您可以使用DMV(也适用于HEAP - 即没有索引的表) - 您可以扩展以加入模式

SELECT 
    OBJECT_NAME(OBJECT_ID) AS TableName, last_user_update AS UpdateDateTime
FROM 
    sys.dm_db_index_usage_stats
WHERE 
    database_id = DB_ID('PUT_DB_NAME')
    AND last_user_update = 'EnterDateTimeHereToFilterOn'