0

我有许多表,我想根据视图动态创建和填充。

我想执行类似这两个帖子的组合:

从视图创建表

有没有办法在不使用游标的情况下循环遍历 TSQL 中的表变量?

Select *
Into dbo.##tblTemp
From databasename.sys.views

Declare @TableName NVARCHAR(128)

While (Select COUNT(*) From #Temp) > 0

Begin

    Select Top 1 @TableName = name from databasename.sys.views

        Select * into @TableName from databasename.sys.views

    Delete databasename.sys.views Where name = @TableName

End

我最好使用动态创建 sql 语句来创建表的存储过程吗?

编辑:

根据 Sebastian,我正在运行以下代码来完成此操作:

DECLARE @cmd NVARCHAR(MAX) = ( SELECT TOP 10 'exec sp_rename '
                                    + '@objname =''' + OBJECT_SCHEMA_NAME(object_id)
                                    + '.'
                                    + OBJECT_NAME(object_id) + ''
                                    + ''', @newname = '
                                    + '''v_' + name + ''
                                    + ''';'
                                    + 'SELECT * INTO '
                                    + OBJECT_SCHEMA_NAME(object_id)
                                    + '.'                                   
                                    + OBJECT_NAME(object_id)
                                    + ' FROM '
                                    + OBJECT_SCHEMA_NAME(object_id)
                                    + '.v_'                                 
                                    + OBJECT_NAME(object_id)
                                    + ';'
                                    + 'DROP VIEW '
                                    + OBJECT_SCHEMA_NAME(object_id)
                                    + '.v_' 
                                    + OBJECT_NAME(object_id)
                                    + ';'
                            FROM db.sys.views
                            FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)');

EXEC (@cmd)
--选择@cmd

4

1 回答 1

1

复制所有数据似乎是解决问题的错误方法。如果您的问题是由于视图导致的读取过多而导致性能不佳,则首先要注意两件事。

1) 检查您的表是否有适当的索引。您甚至可以为视图添加索引。有很多资源可以告诉您如何进行索引调优。或者你可以聘请一位顾问(比如我)来帮助你解决这个问题。

2) 如果您的查询加入视图,则经常会出现不必要的表混入其中。例如,如果视图 v1 连接表 a 和 b,视图 v2 连接表 b 和 c,然后您的查询将 v1 和 v2 连接起来,它实际上将 a 和 b 连接到 b 和 c。这样的查询通常可以重写以仅加入一次 b 极大地提高性能。因此,如果您有将视图与视图连接的查询,您应该查看这些查询。

如果你仍然想继续复制数据,你可以使用这个:

DECLARE @cmd NVARCHAR(MAX) = ( SELECT 'SELECT * INTO '
                                      + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                      + '.'
                                      + QUOTENAME('tbl_'+OBJECT_NAME(object_id))
                                      + ' FROM '
                                      + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                      + '.' + QUOTENAME(OBJECT_NAME(object_id))
                                      + ';'
                               FROM   sys.views
                               FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)');

EXEC (@cmd);     

它创建一个命令,该命令使用 SELECT INTO 为数据库中的每个视图创建一个表。因为即使对于不同类型的对象,SQL Server 也不允许名称冲突,所以我在表的名称前加上“tbl_”。

如果您需要在不同的数据库中创建表,则需要在表名前加上“ dbname.”前缀。在这种情况下,您可以删除“tbl_”前缀。


编辑:

您的版本中缺少一些引号。试试这个:

DECLARE @cmd NVARCHAR(MAX) = ( SELECT TOP 1 'exec sp_rename '''
                                + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                + '.'
                                + QUOTENAME(OBJECT_NAME(object_id))
                                + ''', '''
                                + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                + '.'
                                + QUOTENAME('v_' +OBJECT_NAME(object_id))
                                + ''';'
                                + 'SELECT * INTO '
                                + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                + '.'                                   
                                + QUOTENAME(OBJECT_NAME(object_id))
                                + ' FROM '
                                + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                + '.'                                   
                                + QUOTENAME('v_' +OBJECT_NAME(object_id))
                                + ';'
                                + 'DROP VIEW '
                                + QUOTENAME(OBJECT_SCHEMA_NAME(object_id))
                                + '.' 
                                + QUOTENAME('v_' +OBJECT_NAME(object_id))
                                + ';'
                        FROM sys.views
                        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)');

您也可以使用PRINT @cmd代替EXEC(@cmd)来查看放在一起的命令是否有意义。

于 2013-01-07T21:57:46.693 回答