在典型的运行应用程序中,不太可能看到视图或存储过程变得无效,因为应用程序通常在正常执行期间不会更改表结构,也不会更改视图或存储过程的定义。对表、视图或PL/SQL单元的更改通常发生在应用程序通过补丁脚本或临时的DDL语句进行打补丁或升级时。在应用程序打了补丁以更改一组被引用对象之后,可能会导致依赖对象变为无效。
以下是schema object失效的一些常见的原因:
- 在一个被引用对象和每个其依赖对象之间,数据库会跟踪涉及到依赖关系的被引用对象的元素。例如,如果一个单表视图仅选择表中的一部分列,则只有这些列涉及到依赖关系。对于一个对象的每个依赖者,如果对依赖关系中的任何元素的定义进行了更改(包括删除该元素),则依赖对象将被标记为无效。相反,如果只对不涉及依赖关系的元素的定义进行了更改,则依赖对象仍然有效
- 在许多情况下,如果开发人员在更改schema object时小心谨慎,就可以避免依赖对象的失效以及数据库不必要的额外工作。
- 依赖对象级联失效。 如果任何对象由于任何原因变得无效,则该对象的所有依赖对象都会立即失效。
- 如果在一个模式对象上撤销了任何对象权限,那么依赖对象将被级联使其无效。
DBA_DEPENDENCIES 视图可以用于检查哪些对象依赖于其他对象,然后查询 DBA_OBJECTS 来检查每个依赖对象的 last_ddl_time — 这将指示哪些对象已经发生了变化,并导致它们变为无效。下面的 SQL 语句可以用于调查。
查找对象的所有依赖关系 ,
SELECT *
FROM DBA_DEPENDENCIES DP
WHERE DP.REFERENCED_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
AND DP.REFERENCED_TYPE != 'NON-EXISTENT'
AND DP.NAME = 'TYPE_YOUR_INVALIDATED_OBJECT_NAME'
查找对象(对象内部不含dblink)的所有依赖关系
SELECT *
FROM DBA_DEPENDENCIES DP
WHERE DP.REFERENCED_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
AND DP.REFERENCED_TYPE != 'NON-EXISTENT'
AND DP.REFERENCED_LINK_NAME IS NULL
AND DP.NAME = 'TYPE_YOUR_INVALIDATED_OBJECT_NAME'
检查依赖对象的 last_ddl_time
SELECT DISTINCT DO.OWNER,
DO.OBJECT_TYPE,
DO.OBJECT_NAME,
DO.CREATED,
DO.LAST_DDL_TIME
FROM DBA_DEPENDENCIES DP, DBA_OBJECTS DO
WHERE DP.REFERENCED_OWNER = DO.OWNER
AND DP.REFERENCED_NAME = DO.OBJECT_NAME
AND DP.REFERENCED_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
AND DP.REFERENCED_TYPE != 'NON-EXISTENT'
AND DP.REFERENCED_LINK_NAME IS NULL
AND DP.NAME = 'TYPE_YOUR_INVALIDATED_OBJECT_NAME'
ORDER BY DO.LAST_DDL_TIME DESC
检查 DBA_AUDIT_TRAIL 来查找在依赖对象上运行 DDL 命令的用户
SELECT *
FROM DBA_AUDIT_TRAIL DT
WHERE TIMESTAMP BETWEEN TO_DATE ('24/05/2021 23:00:00',
'DD/MM/YYYY HH24:MI:SS')
AND TO_DATE ('24/05/2021 23:59:00',
'DD/MM/YYYY HH24:MI:SS')
AND DT.OBJ_NAME IN
('TYPE_YOUR_OBJECT_NAME_RESULT_OF_ABOVE_SQL')
ORDER BY 5
查找对象(内含dblink)的所有依赖关系
SELECT *
FROM DBA_DEPENDENCIES DP
WHERE DP.REFERENCED_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
AND DP.REFERENCED_TYPE != 'NON-EXISTENT'
AND DP.REFERENCED_LINK_NAME IS NOT NULL
AND DP.NAME = 'TYPE_YOUR_INVALIDATED_OBJECT_NAME'
检查属于对象(具有dblink的)的依赖对象的 last_ddl_time
SELECT DISTINCT DO.OWNER,
DO.OBJECT_TYPE,
DO.OBJECT_NAME,
DO.CREATED,
DO.LAST_DDL_TIME
FROM DBA_DEPENDENCIES DP, DBA_OBJECTS@dblink
WHERE DP.REFERENCED_OWNER = DO.OWNER
AND DP.REFERENCED_NAME = DO.OBJECT_NAME
AND DP.REFERENCED_OWNER NOT IN ('SYS', 'SYSTEM', 'PUBLIC')
AND DP.REFERENCED_TYPE != 'NON-EXISTENT'
AND DP.REFERENCED_LINK_NAME IS NOT NULL
AND DP.NAME = 'TYPE_YOUR_INVALIDATED_OBJECT_NAME'
ORDER BY DO.LAST_DDL_TIME DESC
检查 DBA_AUDIT_TRAIL 查找在依赖对象上运行 DDL 命令的用户
在 DBLINK 源数据库上运行此命令。
SELECT *
FROM DBA_AUDIT_TRAIL DT
WHERE TIMESTAMP BETWEEN TO_DATE ('24/05/2021 23:00:00',
'DD/MM/YYYY HH24:MI:SS')
AND TO_DATE ('24/05/2021 23:59:00',
'DD/MM/YYYY HH24:MI:SS')
AND DT.OBJ_NAME IN
('TYPE_YOUR_OBJECT_NAME_RESULT_OF_ABOVE_SQL')
ORDER BY 5