使用sysobjects表中的表名创建Sql Server视图

使用sysobjects表中的表名创建Sql Server视图,sql,sql-server,view,sql-server-2012,Sql,Sql Server,View,Sql Server 2012,我有大约200张桌子。我想从所有这些表中创建一个视图。我觉得将所有表名硬编码并在视图定义中执行UNION all,效率很低 相反,我计划从sysobjectstable-like中检索表名 Select name from sysobjects where name like 'Warehouse_Inventory%' 如何使用这些表名并从中创建视图 注意:我只选择了10个常用列。如果表中不存在任何列,我希望为其显示NULL。此查询可能会对您有所帮助 SELECT 'CREATE

我有大约200张桌子。我想从所有这些表中创建一个
视图
。我觉得将所有表名硬编码并在视图定义中执行
UNION all
,效率很低

相反,我计划从
sysobjects
table-like中检索表名

 Select name from sysobjects where name like 'Warehouse_Inventory%'
如何使用这些表名并从中创建
视图


注意:我只选择了10个常用列。如果表中不存在任何列,我希望为其显示NULL。

此查询可能会对您有所帮助

    SELECT 'CREATE VIEW VIEW_NAME AS'
    UNION ALL
    SELECT 'SELECT * FROM ['+NAME+']
    UNION ALL' FROM SYS.TABLES where name like 'Warehouse_Inventory%'

我不知道为什么要使用sys.sysobjects而不是其他sys视图。现在还可以确定为什么要合并所有表时要按表名搜索。。。。。我可能会建议在表和临时表上放置一个光标,以便在有200个表的情况下保存结果,但若您真的想通过union来执行查询,这里有一种方法

建立一个包含10列的列表。然后运行查询。您可能需要调整并添加一些cast/convert函数,以确保所有数据类型都是正确的。这可以通过sys.types和sys.columns动态完成,或者通过更改下面的动态sql来确保所有数据类型都是NVARCHAR(??),然后继续

DECLARE @ListOfColumns AS TABLE (ColumnName VARCHAR(100))
INSERT INTO @ListOfColumns (ColumnName) VALUES ('col1'),('col2'),('col3')

DECLARE @SQLStatement NVARCHAR(MAX)

;WITH cteColumnsTableCross AS (
    SELECT
       SchemaName = s.name
       ,t.schema_id
       ,TableName = t.name
       ,l.ColumnName
    FROm
       @ListOfColumns l
       CROSS JOIN sys.tables t
       INNER JOIN sys.schemas s
       ON t.schema_id = s.schema_id
)


, cteColumns AS (
    SELECT
       x.SchemaName
       ,x.TableName
       ,x.ColumnName
       ,ColumnExists = IIF(c.name IS NOT NULL,1,0)
       ,RowNum = ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY x.TableName DESC)
       --you can add data type by getting from sys.columns and sys.types if desired
    FROM
       cteColumnsTableCross x
       LEFT JOIN sys.tables t
       ON x.TableName = t.name
       AND x.schema_id = t.schema_id
       LEFT JOIN sys.columns c
       ON t.object_id = c.object_id
       AND x.ColumnName = c.name
)

, cteSelectStatements AS (
    SELECT
       TableName = t.name
        ,TableSelect = 'SELECT TableName = ''' + t.name +  ''', ' + 

            STUFF(
            (SELECT ', ' + c.ColumnName + ' = ' + IIF(c.ColumnExists = 0,'NULL',c.ColumnName)
            FROM
                cteColumns c
            WHERE t.name = c.Tablename
            FOR XML PATH(''))
            ,1,1,'')

          + ' FROM ' + t.name + 

          IIF((ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY t.name DESC)) > 1,' UNION ALL ','')
    FROM
       sys.tables t
)

SELECT @SQLStatement = STUFF(
        (SELECT ' ' + TableSelect
        FROM
            cteSelectStatements
       ORDER BY
          TableName
        FOR XML PATH(''))

        ,1,1,'')

PRINT @SQLStatement
--EXECUTE @SQLStatement

除非这些表中的所有列都相同,否则很难对这些表进行联合。为此,您需要动态SQL。如果您要查找的是联接而不是联合,那么您仍然必须对要联接的列进行硬编码。如果它们不存在,我将显示一个空值。如何对所有表执行union all??它们是否具有相同的数据类型和相同的列数??这是他可以查看的内容,但这将导致在运行所有返回的选定语句时出错,因为列列表对于所有表都不相同。此查询打印最后一行的UNION all。如果是一次性活动,则手动删除该UNION all,否则将不得不合并单行使用XML或@Variable删除最后一个UNION ALL。。。。在这种情况下,哪一个比较简单……。:)