自动创建一个视图,该视图将所有其他具有相同名称但不同前缀和不同模式的视图联合起来
Posted
技术标签:
【中文标题】自动创建一个视图,该视图将所有其他具有相同名称但不同前缀和不同模式的视图联合起来【英文标题】:Automagically create a view that unions all other views with the same name but different prefix and different schema 【发布时间】:2020-09-18 14:32:19 【问题描述】:我有一个包含两个或多个架构的数据库。每个架构都包含多个视图。
在架构ALPHA
中,我们发现以下视图:
在架构BETA
中,我们发现以下视图:
我正在寻找的是一个过程,它将创建一个模式ALLTOGETHERNOW
,它将所有具有相同名称的视图联合起来。
所以架构ALLTOGETHERNOW
将如下所示:
以下适用:
预先不知道模式的数量。如有必要,我们可以制作一个表格,列出所有要连接的模式 事先不知道观看次数。 视图总是看起来像vw_<something>_viewname
。我们确实知道具有相同名称的视图具有相同的列。
所以想法是以某种方式循环遍历模式,收集所有视图,减去后缀(vw_<something>
部分,然后创建一个语句来创建合并所有视图的视图。
我一直在玩信息模式等,可以创建一个包含视图名称的列表。但是在那里我遇到了死胡同....
【问题讨论】:
不是你的问题,但你可能会从Create a UNION ALL query when the columns are in different order得到一些提示。 事实上,这似乎更像是一个真正的问题,即你有一个设计缺陷。此处是否使用模式名称来推断数据(例如学校名称)? 这个特定示例中的模式可以是区域。需要将区域保持在单独的模式中。有些人只能看到自己的区域,有些人可以看到所有区域和区域的组合数据。 那为什么不直接实现行级安全呢?与在不同模式中重复对象相比,这将是一个更好的解决方案。这个设计闻起来像XY Problem。 学校只是一个例子。还有其他要求在起作用,我现在不想讨论。看看其他要求,这是与我的几位同事(旧的和现在的)讨论过的最佳解决方案 【参考方案1】:“自动” - 没有魔法,只是读取元数据并生成单个输出查询的动态 SQL:
DECLARE @create_view_sql NVARCHAR(MAX);
WITH vw(t) AS (
SELECT DISTINCT RIGHT(TABLE_NAME, LEN(TABLE_NAME)-5) --assumption prefix has 4 chars
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_SCHEMA NOT IN ('ALTOGETHER', 'dbo')
)
SELECT @create_view_sql = STRING_AGG(s.sql, CHAR(13)) WITHIN GROUP(ORDER BY vw.t)
FROM vw
CROSS APPLY(
SELECT N'EXEC(''CREATE OR ALTER VIEW ALTOGETHER.' + QUOTENAME(N'vw_' + vw.t) + ' AS ' +
STUFF(STRING_AGG(FORMATMESSAGE('UNION ALL SELECT * FROM %s.%s'
,QUOTENAME(TABLE_SCHEMA), QUOTENAME(TABLE_NAME))
, CHAR(13)) WITHIN GROUP(ORDER BY TABLE_NAME), 1,10,'')
+ N''');'
FROM INFORMATION_SCHEMA.VIEWS
WHERE TABLE_NAME LIKE 'vw_[a-z]_' + vw.t
AND TABLE_SCHEMA NOT IN ('ALTOGETHER', 'dbo')
)s(sql);
PRINT @create_view_sql;
EXEC sp_executesql @create_view_sql;
它可以包含在存储过程中并以预定的方式运行。
db<>fiddle.com demo
【讨论】:
这看起来很有希望!!以上是关于自动创建一个视图,该视图将所有其他具有相同名称但不同前缀和不同模式的视图联合起来的主要内容,如果未能解决你的问题,请参考以下文章