2013-01-07 101 views
0

我有很多我想創建並基於視圖動態填充的表格。用表格替換視圖

我要像這兩個職位的組合進行了一句:

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語句來創建存儲過程桌子?

編輯:

每塞巴斯蒂安,我運行下面的代碼來實現:

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

+0

你想達到什麼目的?您是否想爲與視圖具有相同架構的每個視圖創建一個表?你想在這些表中的數據?該觀點應該發生什麼? - 另外,你正在努力解決的底層問題是什麼? –

+0

是的,我希望每個視圖的表具有與視圖相同的架構。是的,我也想填充這些表中的數據。該視圖需要由表格替換。 –

+1

你介意我問你爲什麼需要這樣做嗎?你知道沒有好的機制來保持這些新表中的數據與它最初來自的表同步嗎? –

回答

1

複製所有數據似乎是解決您的問題的錯誤方法。如果你的問題表現不佳,那麼由於視圖造成的讀取次數太多,首先需要注意兩點。

1)檢查你的表是否有適當的索引。你甚至可以爲你的視圖添加索引。有很多資源告訴你如何去做索引調整。或者你可以聘請一位顧問(像我一樣)來幫助你。 2)如果你的查詢加入了視圖,經常會發生不必要的表格使其混合。例如,如果view 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),看看放在一起的命令是有道理的。

+0

工程很棒。但是,因爲我希望表中包含與視圖相同的名稱。因此,在創建表時應該刪除該視圖。 –

+0

你可以添加'+'DROP VIEW'+ QUOTENAME(OBJECT_SCHEMA_NAME(object_id))+'。' + QUOTENAME(OBJECT_NAME(object_id))+';''在'+'之後;''然後類似於'EXEC sp_rename'。 - 但是,如果您刪除了視圖,您將有機會進行數據刷新,所以我強烈建議不要這樣做。也許你可以重新命名視圖,然後用原來的名字創建表格。 –

+0

我在開發環境中工作,所以我對丟失數據感到滿意(如果需要,我可以從備份中恢復數據)。什麼時候需要執行sp_rename,以便創建的表仍包含原始視圖? –