用表替换视图

时间:2013-01-07 17:34:29

标签: sql-server-2008 tsql

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

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

Create Table from View

Is there a way to loop through a table variable in TSQL without using a cursor?

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语句来创建表吗?

编辑:

Per 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

1 个答案:

答案 0 :(得分:1)

复制所有数据似乎是解决问题的错误方法。如果您的问题表现不佳,那么由于视图引起的读取过多,首先需要注意两件事。

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

2)如果您的查询加入了视图,那么经常会出现不必要的表格进入混合视图。例如,如果视图v1连接表a和b并且视图v2连接表b和c并且您的查询然后将v1与v2连接,则它实际上将b与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)来查看放在一起的命令是否有意义。