为 CASCADE 之后的视图重新创建创建数据库视图依赖关系树

Posted

技术标签:

【中文标题】为 CASCADE 之后的视图重新创建创建数据库视图依赖关系树【英文标题】:Create Database View Dependency Tree for View Recreation after CASCADE 【发布时间】:2019-06-25 13:28:14 【问题描述】:

我的数据库中有一个视图,其中每条记录都有两列:源和依赖。在源列中是数据库中表/视图的名称,它是从属列中找到的视图名称的来源。使用 Python,我想创建另一个表,当使用 CASCADE 删除源表时,可以使用该表重新创建视图。

我知道我可以在 SQL 中对每个“级别”的依赖项使用 CTE 来做到这一点。但是,我必须对每个级别进行硬编码,并且我需要级别数是动态的,以适应数据库中实现的级别数。例如,如果视图“b”依赖于表“a”,则有两个级别,我可以为这两个级别编写代码。但是如果创建了视图“c”,依赖于视图“b”,现在有 3 个级别,我需要知道添加的级别并将其添加到我的代码中。

【问题讨论】:

【参考方案1】:

您可以通过使用递归 CTE 的 SQL 来获得所需的内容。为了可视化,我为您的示例添加了一个额外的级别。

--- set up 
create table view_dependencies (source_view text, depends_on_view text);

insert into view_dependencies( source_view, depends_on_view)
values ('b','a'), ('c','b'), ('d','c');

select * from view_dependencies;

-- show dependencies  
with RECURSIVE view_depends as (
   select source_view, depends_on_view, 1 lev
     from view_dependencies 
    where depends_on_view = 'a'
    UNION ALL
    select v.source_view, v.depends_on_view, lev+1
     from view_dependencies v
     join view_depends d on (v.depends_on_view = d.source_view)) 
SELECT * FROM view_depends;

-- extend the dependencies 
insert into view_dependencies( source_view, depends_on_view)
values ('g','d');

-- run the show dependencies query again.

由于您使用的工具不允许递归 CTE,我首先会看到它提供了传递原始 SQL 语句的能力(或者可能更新工具)。但是假设它也不可用,也许你可以在它周围包装一个函数,如下所示。

create or replace function view_dependent_tree(base_view  text)
                   returns table (source_view text
                                 ,depends_on  text
                                 ,lev         integer
                                 ) 
 language plpgsql                                    
as $$
begin 
    for source_view 
       ,depends_on   
       ,lev    
    in  
        with RECURSIVE view_depends as (
             select d.source_view, d.depends_on_view, 1 lev
               from view_dependencies d
              where depends_on_view = base_view 
              UNION ALL
              select v.source_view, v.depends_on_view,d.lev+1
                from view_dependencies v
                join view_depends d on (v.depends_on_view = d.source_view)) 
        SELECT * FROM view_depends      
    loop
        return next;
    end loop; 
    return;
end; 
$$ ;   

select source_view, depends_on, lev from view_dependent_tree('a'); 

您是否应该提到您无法使用递归 CTE?好吧,这会很好,但这样做会暗示先验知识,这将是建议。我假设不是;不用担心。

【讨论】:

这太棒了!不幸的是,我使用的 Redshift 版本不支持递归查询。我应该指定的。

以上是关于为 CASCADE 之后的视图重新创建创建数据库视图依赖关系树的主要内容,如果未能解决你的问题,请参考以下文章

如果底层表结构发生变化,我们是不是需要重新创建物化视图

mysql中的视图

用SQL代码创建一个视图,并查询视图中的字段

SQL中视图的创建。修改,删除

mysql-视图及索引简介

Oracle - 视图相关