将表插入SQL Server视图
我做了一系列的研究,并试图找出如何做到这一点,但所建议的一切似乎都不适合我。我使用以下SQL创建了一个表:将表插入SQL Server视图,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我做了一系列的研究,并试图找出如何做到这一点,但所建议的一切似乎都不适合我。我使用以下SQL创建了一个表: CREATE VIEW view_name AS SELECT * FROM table1_name 当我这样做时,如果我对表1\u name进行更改,这些更改将反映在视图中(如我所愿)。但是,我稍后创建了一个表table2\u name,并希望以相同的方式将其添加到此视图中,以便在向表中添加行时,它们将反映在视图中。因此,我使用了一段类似的代码(但使用insert) 但是,现在当我添加
CREATE VIEW view_name AS SELECT * FROM table1_name
当我这样做时,如果我对表1\u name
进行更改,这些更改将反映在视图中(如我所愿)。但是,我稍后创建了一个表table2\u name
,并希望以相同的方式将其添加到此视图中,以便在向表中添加行时,它们将反映在视图中。因此,我使用了一段类似的代码(但使用insert)
但是,现在当我添加到表2\u name
时,这些内容不会反映在视图中。我对SQL(三天前开始)非常陌生,所以我非常感谢您的任何想法或地方
(注意:我使用的是SQL Server,我似乎不认为这有多大区别,但万一有区别的话)
谢谢,
SaxyTimmy您不能以您认为可以的方式将数据插入视图中。运行insert语句时,实际上是在将数据插入视图引用的基表(
table1\u name
)。您没有在视图和table2\u name
的行之间创建某种链接,这可能是您想要做的(假设列相同):
正如Joe指出的,您不会将数据插入到视图中——它不会被持久化(除非它被索引,在这种情况下,您也不会实际插入到视图中)
如果要更新新表的视图,可以执行以下操作。我假设你使用的是SQLServer2005或更好的版本——如果你的学校在教你SQLServer2000,那就太可惜了。我还假设了一些其他的事情。。。您的视图不包含尾随语句终止符(这大概是我唯一一次主张省略它),并且在CREATEVIEW命令之前,您的注释中没有各种各样的废话
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
但正如我在评论中所说,这确实不是你想要的方式,我怀疑你的教授也会有同样的感觉。我认为你误解了一种观点的确切含义。视图基本上只是一个存储的查询。实际上,您并没有将行插入到视图中。虽然您可以有一个可更新的视图,但它将行插入到基础表中 如果要将
table2\u name
添加到视图中,则需要更改该视图定义。如果列完全匹配表1\u name
,则可以执行以下操作:
ALTER VIEW view_name
AS
SELECT
*
FROM
table1_name
UNION ALL
SELECT
*
FROM
table2_name
或者,您可以删除
并创建具有新定义的视图,而不是使用ALTER
语法
另外,当您说“如果我更改了表1的名称”时,您是指插入行还是添加列?您不能将数据插入到视图中。insert将数据插入表1\u name
表。(见附件)
如果要同时从table1\u name
和table2\u name
中获取数据,则必须在创建视图所基于的选择中同时包含table1\u name
和table2\u name
为此,您可以使用或*(如果您查询的两个表都具有相同的no/type/set列):
这要求table1\u name
和table2\u name
具有相同顺序的相同列数和类型
或您可以与另一个表联接并获取所有列(或它们的子集):
*UNION
删除两个select查询之间的重复项<如果您确定两个表中的数据是互斥的,或者如果您对重复的行没有意见,那么code>UNION ALL
是一个更好的选择UNION ALL
性能更好。视图引用的基表是什么?在我的示例中,这是表1\u名称吗?我看了一下,这里没有添加新数据。强烈建议避免使用SELECT*,尤其是在视图中。是的,它更容易键入,但以后可能会导致问题,特别是在模式不断演变的情况下。使用SELECT*意味着每次更改基础表时都需要刷新视图。您应该始终明确指定所需的列。看起来我们将在元数据领域冒险,您可以标记和/或指定您使用的SQL Server版本吗?这些信息在前面总是有用的。我使用的是MS SQL Server 2008,很抱歉,我的意思是插入行。我试着将ALTER VIEW\u name改为SELECT*从表1\u name UNION ALL SELECT*从VIEW\u name这有意义吗?我想保留旧视图,并将此新表添加到其中?谢谢事实上,我自己也能回答。不,这没有意义,你不能自我引用一个视图。你知道我该怎么做类似的事情吗?再说一遍,你看视图的方式不对。它们不是持久化的表/对象。它们只是一个查询定义。想象一下,我正在为我的女儿制作一个家庭视频,但画面中只有一个。我没有把另一个女儿画到相机镜头上,我改变了相机的视角,使它们都适合照片。是的,没错。我想通过“缩小”视图来更新视图,在视图中,我只需要添加更多的内容(镜头边框上的内容)。然后,您需要更改视图定义以添加这些额外的表,就像我所做的那样。看起来Aaron的回答中的评论朝着正确的方向发展,所以我会坚持这一点,而不是保持两种对话。我认为你仍然误解了观点的概念。视图中没有数据。。。它不是表的副本,只是指向表的指针。或者您的意思是不想每次都重新创建视图定义?当你说“视图中的表”时,不管你是指实际数据还是表的引用,我都很难理解
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
ALTER VIEW view_name
AS
SELECT
*
FROM
table1_name
UNION ALL
SELECT
*
FROM
table2_name
CREATE VIEW view_name AS
SELECT * FROM table1_name
UNION
SELECT * FROM table2_name
CREATE VIEW view_name AS
SELECT *
FROM table1_name join table2_name on some_column