我有一个名为 employee_vw 的视图,其中包含以下查询:
select function_standard(ename) from employees;
我想找出列上应用了哪些函数。我尝试使用select dbms_metadata.get_ddl('COLUMN','ENAME','HR') FROM DUAL
,但没有看到列对象类型。
我的要求是能够列出应用于整个数据库中指定列的所有函数。有什么办法可以找出来吗?
提前致谢。
我有一个名为 employee_vw 的视图,其中包含以下查询:
select function_standard(ename) from employees;
我想找出列上应用了哪些函数。我尝试使用select dbms_metadata.get_ddl('COLUMN','ENAME','HR') FROM DUAL
,但没有看到列对象类型。
我的要求是能够列出应用于整个数据库中指定列的所有函数。有什么办法可以找出来吗?
提前致谢。
概述
您正在为所调查视图 ( ) 的每个列定义术语寻找以下类型的信息employee_vw
:
AFAIK 数据字典不维护列级别的依赖关系。但是,可以查询表/视图和函数之间的列目录和依赖关系。使用此信息,可以估计所需的结果。
利用三种信息:
employee_vw
) 和任何函数之间的依赖关系。employee_vw
) 与其基表和视图之间的依赖关系employee_vw
)。前两种数据可通过dba_dependencies
系统视图获得。对于最后一项,来自基表/视图的所有列名都与视图定义文本匹配,限制任何列名的出现,使得它必须以任何引用函数的名称开头。
询问
以下查询实现了上面的想法:
SELECT fndep.referenced_name function_name
, tcol.column_name column_name
, tcol.table_name container_name
FROM dba_dependencies fndep
JOIN dba_dependencies tabdep ON (tabdep.name = fndep.name AND tabdep.type = fndep.type)
JOIN all_views v ON v.view_name = fndep.name
JOIN all_tab_cols tcol ON (tcol.table_name = tabdep.referenced_name)
WHERE fndep.referenced_type = 'FUNCTION'
AND fndep.type = 'VIEW'
AND fndep.name = UPPER('employee_vw')
AND tabdep.referenced_type IN ( 'TABLE', 'VIEW' )
AND lower(v.text_vc) LIKE lower('%'||fndep.referenced_name||'%'||tcol.column_name||'%')
;
基表/视图实际上可能是同义词。以下查询适合这种情况:
SELECT fndep.referenced_name function_name
, tcol.column_name column_name
, tcol.table_name container_name
FROM dba_dependencies fndep
JOIN dba_dependencies tabsyndep ON (tabsyndep.name = fndep.name AND tabsyndep.type = fndep.type)
JOIN dba_synonyms syn ON (syn.synonym_name = tabsyndep.referenced_name)
JOIN dba_tab_cols tcol ON (tcol.table_name = syn.table_name)
JOIN dba_views v ON v.view_name = fndep.name
WHERE fndep.referenced_type = 'FUNCTION'
AND fndep.type = 'VIEW'
AND fndep.name = UPPER('employee_vw')
AND tabsyndep.referenced_type IN ( 'SYNONYM' )
AND lower(v.text_vc) LIKE lower('%'||fndep.referenced_name||'%'||tcol.column_name||'%')
;
请注意,来自 plsql 包的函数可能会应用于列定义。如果您需要考虑到这一点,fndep.referenced_type IN ( 'FUNCTION', 'PACKAGE' )
请在 where 条件下使用。
注意事项
解决方案是仅具有(至少)这些缺陷的近似值:
dba_views.text_vc
限制为 4000 个字符。但是,实际定义的长度可能最多为 32767 个字符。后一种情况可以通过检查视图定义长度来检测。完整的文本也可以在 column 中找到dba_views.text
,不幸的是数据类型long
不容易操作。(假阴性;边缘情况下的假阳性)如果您的视图定义超过 4000 的长度,您最好在dba_views
临时表中复制调查视图的记录,替换text
为等效的 clob 列。转换可以使用to_lob
. 当心这篇文章中勾勒的错综复杂的东西。
我不知道如何在不求助于成熟的 sql 解析的情况下规避其他警告。