2011-07-19 60 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表现更好。