使用派生表将视图查询转换为单个查询

时间:2015-01-16 17:02:47

标签: sql sql-server sql-server-2012 sql-view

是否可以将一个包含视图中很多视图的查询转换(如在查询中作为文本)查询到基于原始表的查询中?

显而易见的是要查看所有视图,然后手动完成,但想知道是否有更快的方法?

1 个答案:

答案 0 :(得分:1)

它不漂亮,就像@David Faber评论的那样,不确定这会有多实用,但是这里有......

有很多假设必须要让它起作用,比如

  • 所有视图都以SELECT开头。 (没有CTE)
  • 在另一个视图中引用时,视图未包含在[]中
  • 视图名称中没有空格
  • 此版本只有1级深度,但应该可以以类似的方式解析您在输出中找到的任何其他视图。
  • 可能还有一些我没想到的

我正在使用sys表,而不是更新的架构信息对象,因为我更了解sys表结构。

假设以下视图

CREATE VIEW VW_DUMMY
AS
SELECT c.Name as Company, g.Name as [Group], gu.UserId
FROM VW_Company c
    JOIN VW_Group g ON c.Id = g.CompanyId
    JOIN VW_GroupUser gu ON g.Id = gu.GroupId AND gu.CompanyId = c.Id

这就是我的所作所为。

1)从syscomments中获取VW_DUMMY的视图定义。

2)剥离CREATE VIEW部分

2)从sysdepends

中获取VW_DUMMY所依赖的对象列表

3)从syscomments中获取所有依赖对象的视图定义。

4)剥离CREATE VIEW部分

5)用原始视图替换'depends'对象的名称  定义...

1)

DECLARE @SQL    VARCHAR(MAX);
SET @SQL = REPLACE((
    SELECT c.text AS [text()]
    FROM syscomments c 
    WHERE c.id = OBJECT_ID('VW_DUMMY')
    FOR XML PATH('')), '
', '');

2)

SET @SQL = SUBSTRING(@SQL, PATINDEX('%SELECT%', @SQL), LEN(@SQL))

3),4)和5)

SELECT @SQL = REPLACE(@SQL, ' ' + name + ' ', '(' + SUBSTRING(text, PATINDEX('%SELECT%', text), LEN(text)) + ') ')
FROM (
    SELECT DISTINCT OBJECT_NAME(depid) as name,
    REPLACE((
        SELECT c.text AS [text()]
        FROM syscomments c 
        WHERE c.id = d.depid
        FOR XML PATH('')), '
', '') as text
    FROM sysdepends d
WHERE d.id = OBJECT_ID('VW_DUMMY')
AND exists(select 1 from sysobjects c where c.id = d.depid and c.type='V')) data

SELECT @SQL

我尝试在我的数据库中使用VW_DUMMY,输出是您可能看到的一些格式最差的代码,但结果与视图相同。

这是输出(故意格式化是故意的)

SELECT c.Name as Company, g.Name as [Group], gu.UserId
FROM(SELECT *
FROM Company


) c
    JOIN(SELECT *
FROM [Group]



) g ON c.Id = g.CompanyId
    JOIN(SELECT *
FROM [GroupUser]



) gu ON g.Id = gu.GroupId AND gu.CompanyId = c.Id

这有帮助吗?