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

Posted

技术标签:

【中文标题】使用 sysobjects 表中的表名创建 Sql Server 视图【英文标题】:Create Sql Server view using table name from sysobjects table 【发布时间】:2016-06-22 05:39:54 【问题描述】:

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

相反,我打算从sysobjects 表中检索表名

 Select name from sysobjects where name like 'Warehouse_Inventory%'

如何使用这些表名并从中创建一个view

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

【问题讨论】:

除非这些表中的所有列都相同,否则很难对这些表进行联合。为此,您需要动态 SQL。如果您要查找的是 JOIN 而不是 UNION,那么您仍然必须对要连接的列进行硬编码。 可以说,我只选择所有表中存在的列。如果它们不存在,我将显示 NULL。 如何联合所有表?它们是否具有相同的数据类型和相同的列数?? 【参考方案1】:

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

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

【讨论】:

这是他可以查看的内容,但这会在运行所有返回的选定语句时出错,因为所有表的列列表都不相同。 此查询为最后一行打印 UNION ALL。 如果是一次活动手动删除那个 UNION ALL,否则它将使用 XML 或 @Variable 合并到单行以删除最后一个 UNION ALL....在这种情况下哪个很简单.. ...... :)【参考方案2】:

我不确定您为什么要使用 sys.sysojects 而不是其他 sys 视图。现在也知道为什么当你想联合所有表时你想通过一个表名搜索.....如果你有 200 个表的大小,我可能会建议在表和临时表上使用一个游标来保存你的结果查询但如果你真的想通过联合来做这一切都是一种方式......

建立一个包含 10 列的列表。然后运行查询。您可能需要调整并添加一些转换/转换功能以确保一切都是正确的数据类型,这可以使用 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

【讨论】:

以上是关于使用 sysobjects 表中的表名创建 Sql Server 视图的主要内容,如果未能解决你的问题,请参考以下文章

sql 获取每个表中的表名和记录计数

SqlServer如何查询表的列数

Java 中获得Access 数据库中的表名和表中的列名 及每个列的数据类型

查找一个字段所在的表名数据库名

SQL Server系统表sysobjects介绍与使用(转))

SQL Server 2000中查询表名,列名及字段类型