【问题标题】:How to get the functions name used by a column in the whole database?如何获取整个数据库中某列使用的函数名?
【发布时间】:2018-02-01 10:34:18
【问题描述】:

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

select function_standard(ename) from employees; 

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

我的要求是能够列出应用于整个数据库中指定列的所有函数。有什么办法可以找出来吗?

提前致谢。

【问题讨论】:

    标签: sql plsql oracle11g dbms-metadata


    【解决方案1】:

    概述

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

    1. 列定义项与系统中任何函数之间的依赖关系
    2. 列定义术语与任何基础视图/表的列之间的依赖关系

    AFAIK 数据字典不维护列级别的依赖关系。但是,可以查询表/视图和函数之间的列目录和依赖关系。使用此信息,可以近似得出所需的结果。

    利用三种信息:

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

    注意事项

    解决方案是仅具有(至少)以下缺陷的近似值:

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

    如果您的视图定义超过 4000 的长度,您最好在临时表中复制被调查视图的 dba_views 记录,用等效的 clob 列替换 text。可以使用to_lob 完成转换。 注意this article 中描述的复杂性

    我不知道如何在不求助于成熟的 sql 解析的情况下规避其他警告。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 2019-09-03
      • 2023-02-09
      • 2018-03-30
      • 2016-08-08
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      相关资源
      最近更新 更多