2011-07-19 63 views
2

我已經完成了一系列研究並試圖弄清楚如何執行此操作,但所有建議的內容似乎都不適用於我。我創建使用下面的SQL表:將表插入到SQL Server視圖中

CREATE VIEW view_name AS SELECT * FROM table1_name 

當我這樣做,如果我做出這些變化反映在視圖改變table1_name(我想)。但是,後來我創建了一個表table2_name並希望以相同的方式將它添加到此視圖中,以便如果向表中添加行,它們將反映在視圖中。所以,我使用了類似的一段代碼,(但使用插入代替)

INSERT INTO view_name SELECT * FROM table2_name 

但是,現在當我做出補充table2_name這些都沒有反映在視圖。我非常新的SQL(三天前開始),所以我應該看看任何想法或地方將非常感激。

(注:我使用的SQL Server中,我似乎並不認爲這使多大的差別,但如果它確實)

感謝, SaxyTimmy

+3

強烈建議避免使用SELECT *,特別是在視圖中。是的,輸入起來比較容易,但以後可能會導致問題,特別是在架構不斷髮展的情況下。使用SELECT *意味着每次更改基礎表時都需要刷新視圖。你應該總是明確地指定你想要的列。 –

+0

看起來我們要在元數據的領域冒險,可以請您標記和/或指定您正在使用的SQL Server的版本?這個信息總是*預先有用。 –

+0

我正在使用MS SQL Server 2008,對此感到抱歉 – SaxyTimmy

回答

3

您不能插入數據以您認爲可以的方式進入視圖。在運行插入語句時,實際上是將數據插入到視圖引用的基表(table1_name)中。您不會在視圖和table2_name的行之間創建某種鏈接。

+0

視圖引用的基表?在我的例子中,這是table1_name嗎?我看着這裏,並沒有添加新的數據。 – SaxyTimmy

6

也許你的意思做(假設列是相同的):

ALTER VIEW view_name 
AS 
    SELECT col1, col2 FROM table1_name 
    UNION ALL 
    SELECT col1, col2 FROM table2_name 

喬指出的那樣,你不插入數據視圖 - 這是不持久(除非它被收錄,在這種情況下,你實際上並沒有插入到視圖中)。

如果你想更新新表的視圖,你可以做這樣的事情。我假設你使用的是SQL Server 2005或更高版本 - 如果你的學校教你SQL Server 2000,那麼對他們感到羞恥。我還假設了其他一些事情......你的觀點不包含一個尾隨語句終結者(關於我唯一一次主張將它拋出去),而且你之前的評論中沒有任何廢話CREATE VIEW命令。

CREATE PROCEDURE dbo.AddTableToView 
    @view  SYSNAME, 
    @new_table SYSNAME 
AS 
BEGIN 
    SET NOCOUNT ON; 

    DECLARE @sql NVARCHAR(MAX); 

    SELECT @sql = [definition] FROM sys.sql_modules 
     WHERE [object_id] = OBJECT_ID(@view); 

    SELECT @sql = STUFF(@sql, CHARINDEX('CREATE VIEW', @sql), 6, 'ALTER') 
     + 'UNION ALL 
      SELECT col1, col2 FROM ' + @new_table; 

    EXEC sp_executeSQL @sql; 
END 
GO 

但正如我在評論中所建議的那樣,這真的不是你想要去的方式,我懷疑你的教授會有同樣的感覺。

+0

這看起來很有希望。但是,如果視圖中有大量表格呢?有什麼方法可以使用當前視圖的內容並添加到它上面? – SaxyTimmy

+3

我認爲你仍然誤解了一個觀點的概念。沒有數據* IN *視圖...它不是表的副本,它只是一個指向表的指針。或者你的意思是說你不想每次都重新創建視圖定義?當你說「視圖中的表格」時,我很難跟蹤到你是指實際數據還是表格的引用。 –

+2

如果您將大量相同的表添加到視圖中,則可能表示數據庫設計存在問題。 –

3

我認爲你誤解了什麼是一個視圖。一個視圖基本上只是一個存儲的查詢。您實際上不會將行插入視圖中。儘管您可以擁有可更新的視圖,但它將行插入到基礎表中。

如果您想將table2_name添加到視圖中,則需要更改該視圖定義。如果列完全匹配table1_name那麼你可以這樣做:

ALTER VIEW view_name 
AS 
    SELECT 
     * 
    FROM 
     table1_name 
    UNION ALL 
    SELECT 
     * 
    FROM 
     table2_name 

或者,您可以DROPCREATE新的定義,而不是使用ALTER語法的觀點。

此外,當你說,「如果我對table1_name進行了更改」,你的意思是插入行或添加列?

+0

我的意思是插入行。我試圖做 ALTER VIEW VIEW_NAME AS SELECT * FROM table1_name UNION ALL SELECT * FROM VIEW_NAME 這是否有道理?我想保留舊的視圖,並添加這個新的表格? 謝謝! – SaxyTimmy

+0

我可以自己回答。不,這沒有意義,你不能自我引用視圖。有關我如何能做類似的事情的任何想法? – SaxyTimmy

+0

再次,您正在以錯誤的方式看待視圖。他們不是一個持久的表/對象。它們只是一個查詢定義。想象一下,我正在製作我的女兒的家庭視頻,但只有一個在框架中。我沒有把另一個女兒拉到相機鏡頭上,我改變了相機的視角,使它們都適合照片。 –

2

您無法將數據插入到視圖中。您的插入將數據插入到table1_name表中。 (見Updatable and Insertable Views

如果你想從兩個table1_nametable2_name數據,那麼你必須有在基於select在其上創建的視圖都table1_nametable2_name

可以使用要麼UNION *爲(如果同時你從查詢表具有相同的無/類型/列):

CREATE VIEW view_name AS 
SELECT * FROM table1_name 
UNION 
SELECT * FROM table2_name 

這就要求table1_nametable2_name具有相同數量和在同一順序

或者您可以與其他表連接,並得到所有的列(或它們的子集)類​​型的列:

CREATE VIEW view_name AS 
SELECT * 
FROM table1_name join table2_name on some_column 

* UNION刪除兩個select查詢之間的重複項。如果您確定來自兩個表的數據是相互排斥的,或者您對重複行可以,那麼UNION ALL是更好的選擇。 UNION ALL表現更好。