如何获取整个数据库中列使用的函数名称?

时间:2018-02-01 10:34:18

标签: sql plsql oracle11g dbms-metadata

我有一个名为employee_vw的视图,其中包含以下查询:

select function_standard(ename) from employees; 

我想找出哪些函数应用于列。我尝试使用select dbms_metadata.get_ddl('COLUMN','ENAME','HR') FROM DUAL,但没有看到列对象类型。

我的要求是能够列出应用于整个数据库中指定列的所有函数。有没有办法找到这个?

提前致谢。

1 个答案:

答案 0 :(得分:1)

<强>概述

您正在为调查视图的每个列定义术语(employee_vw)寻找以下类型的信息:

  1. 列定义术语与系统中任何函数之间的依赖关系
  2. 列定义术语与任何基本视图/表的列之间的依赖关系
  3. AFAIK对列级别的依赖性由数据字典维护。但是,可以查询表/视图和函数之间的列目录和依赖关系。使用此信息,可以近似得到所需的结果。

    开发了三种信息:

    1. 调查视图(employee_vw)与任何函数之间的依赖关系。
    2. 调查视图(employee_vw)及其基表和视图之间的依赖关系
    3. 在调查视图(employee_vw)的列定义术语中出现基表/视图列。
    4. 前两种数据可通过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包中的函数可能会应用于列定义中。如果您需要考虑到这一点,请在where条件中使用fndep.referenced_type IN ( 'FUNCTION', 'PACKAGE' )

      <强>注意事项

      解决方案只是(至少)这些缺陷的近似值:

      • 引用函数和基表/视图列的名称可能出现在不同的列定义术语中。 (误报)
      • 引用函数的名称和基表/视图列可能出现在字符串文字中。 (误报)
      • dba_views.text_vc提供的视图定义文字限制为4000个字符。但是,实际定义的长度最多可达32767个字符。可以通过检查视图定义长度来检测后一种情况。完整的文本也可以在dba_views.text列中找到,遗憾的是数据类型long无法轻松操作。 (漏报;边缘案例中的误报)

      如果您的视图定义超过了4000的长度,那么最好在临时表中复制调查视图的dba_views记录,并用等效的clob列替换text。转换可以使用to_lob完成。 谨防<{3}}中草拟的错综复杂

      我不知道如何在不诉诸完整的SQL解析的情况下绕过其他警告。