Oracle 函数获取模式中所有表的最后更新时间戳
Oracle Function to Get Last Updated Timestamps For All Tables In A Schema
我编写了以下函数:
declare
v_count DATE;
strsql VARCHAR2(200);
begin
for r in (select OBJECT_NAME from all_objects where OBJECT_TYPE='TABLE'
and OWNER='SALES'
and OBJECT_NAME LIKE 'T%'
ORDER BY OBJECT_NAME DESC)
loop
DBMS_OUTPUT.PUT_LINE(r.OBJECT_NAME);
strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM : 1 INTO v_count';
execute immediate strsql USING r.OBJECT_NAME;
DBMS_OUTPUT.PUT_LINE(v_count);
end loop;
end;
不幸的是,有两件(坏的)事情正在发生:
- 它只输出第一个OBJECT_NAME(第一个PUT_LINE)。
- 它不执行第二个 PUT_LINE。
显然,我不是 Oracle 开发人员,我只需要一个快速而简单的函数来显示给定模式中所有表的最后更新时间。
谁能告诉我我做错了什么?
您的 strsql 包含不正确的 SQL,无法执行。所以,首先 execute immediate
引发异常(你肯定看到了)。
Table 名称不能从参数中使用。你应该像
strsql := 'select .... from ' || r.owner || '.' || r.object_name;
经过一番折腾,折腾,请教大神Google,想出了这个功能:
declare
v_count TIMESTAMP;
strsql VARCHAR2(200);
tblname VARCHAR2(32);
begin
for r in (select OBJECT_NAME from all_objects where OBJECT_TYPE='TABLE'
and OWNER='SALES'
and OBJECT_NAME LIKE 'T%'
ORDER BY OBJECT_NAME)
loop
begin
tblname := R.OBJECT_NAME;
strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM SALES.' || tblname;
execute immediate strsql into v_count;
DBMS_OUTPUT.PUT_LINE(tblname || ' ' || v_count);
EXCEPTION
when others then
null;
end;
end loop;
end;
ORA_ROWSCN 的保留时间有限,因此如果不保留,将抛出异常。如果我写这个 "correctly",它只会 return ORA-006550 的 null,我会想出一种方法来按 SCN(但降序)对结果进行排序。
请将v_count的日期类型改为timestamp,strsql中的select子句改为如下。
SQL> declare
2 v_count timestamp;
3 strsql VARCHAR2(200);
4 begin
5
6 for r in (select OBJECT_NAME from all_objects
7 where OBJECT_TYPE='TABLE'
8 and OWNER='SCOTT'
9 and OBJECT_NAME like'T%'
10 )
11 loop
12 DBMS_OUTPUT.PUT_LINE(r.OBJECT_NAME);
13 strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM '||r.OBJECT_NAME || ' ';
14 execute immediate strsql into v_count;
15 DBMS_OUTPUT.PUT_LINE(v_count);
16 end loop;
17
18 end;
19 /
TESTEMP
21-APR-15 11.52.20.000000 AM
TESTEMP2
20-APR-15 09.53.12.000000 PM
TEST_AUDIT
21-APR-15 11.52.20.000000 AM
PL/SQL procedure successfully completed.
我编写了以下函数:
declare
v_count DATE;
strsql VARCHAR2(200);
begin
for r in (select OBJECT_NAME from all_objects where OBJECT_TYPE='TABLE'
and OWNER='SALES'
and OBJECT_NAME LIKE 'T%'
ORDER BY OBJECT_NAME DESC)
loop
DBMS_OUTPUT.PUT_LINE(r.OBJECT_NAME);
strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM : 1 INTO v_count';
execute immediate strsql USING r.OBJECT_NAME;
DBMS_OUTPUT.PUT_LINE(v_count);
end loop;
end;
不幸的是,有两件(坏的)事情正在发生:
- 它只输出第一个OBJECT_NAME(第一个PUT_LINE)。
- 它不执行第二个 PUT_LINE。
显然,我不是 Oracle 开发人员,我只需要一个快速而简单的函数来显示给定模式中所有表的最后更新时间。
谁能告诉我我做错了什么?
您的 strsql 包含不正确的 SQL,无法执行。所以,首先 execute immediate
引发异常(你肯定看到了)。
Table 名称不能从参数中使用。你应该像
strsql := 'select .... from ' || r.owner || '.' || r.object_name;
经过一番折腾,折腾,请教大神Google,想出了这个功能:
declare
v_count TIMESTAMP;
strsql VARCHAR2(200);
tblname VARCHAR2(32);
begin
for r in (select OBJECT_NAME from all_objects where OBJECT_TYPE='TABLE'
and OWNER='SALES'
and OBJECT_NAME LIKE 'T%'
ORDER BY OBJECT_NAME)
loop
begin
tblname := R.OBJECT_NAME;
strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM SALES.' || tblname;
execute immediate strsql into v_count;
DBMS_OUTPUT.PUT_LINE(tblname || ' ' || v_count);
EXCEPTION
when others then
null;
end;
end loop;
end;
ORA_ROWSCN 的保留时间有限,因此如果不保留,将抛出异常。如果我写这个 "correctly",它只会 return ORA-006550 的 null,我会想出一种方法来按 SCN(但降序)对结果进行排序。
请将v_count的日期类型改为timestamp,strsql中的select子句改为如下。
SQL> declare
2 v_count timestamp;
3 strsql VARCHAR2(200);
4 begin
5
6 for r in (select OBJECT_NAME from all_objects
7 where OBJECT_TYPE='TABLE'
8 and OWNER='SCOTT'
9 and OBJECT_NAME like'T%'
10 )
11 loop
12 DBMS_OUTPUT.PUT_LINE(r.OBJECT_NAME);
13 strsql := 'select SCN_TO_TIMESTAMP(MAX(ORA_ROWSCN)) FROM '||r.OBJECT_NAME || ' ';
14 execute immediate strsql into v_count;
15 DBMS_OUTPUT.PUT_LINE(v_count);
16 end loop;
17
18 end;
19 /
TESTEMP
21-APR-15 11.52.20.000000 AM
TESTEMP2
20-APR-15 09.53.12.000000 PM
TEST_AUDIT
21-APR-15 11.52.20.000000 AM
PL/SQL procedure successfully completed.