SQL Server等效于Oracle的CREATE OR REPLACE VIEW


115

在Oracle中,我可以用一个语句重新创建视图,如下所示:

CREATE OR REPLACE VIEW MY_VIEW AS
SELECT SOME_FIELD
FROM SOME_TABLE
WHERE SOME_CONDITIONS

就像语法所暗示的那样,这将删除旧视图并使用我给出的任何定义重新创建它。

MSSQL(SQL Server 2005或更高版本)中是否有等效的工具可以执行相同的操作?

Answers:


103

上面的解决方案虽然可以完成工作,但是这样做有可能会丢失用户权限。我更喜欢如下创建或替换视图或存储过程。

IF NOT EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[vw_myView]'))
    EXEC sp_executesql N'CREATE VIEW [dbo].[vw_myView] AS SELECT ''This is a code stub which will be replaced by an Alter Statement'' as [code_stub]'
GO

ALTER VIEW [dbo].[vw_myView]
AS
SELECT 'This is a code which should be replaced by the real code for your view' as [real_code]
GO

2
我曾经是“掉落”的人,然后是(重新)“添加”的人。但是现在我倾向于这种解决方案(如果不存在,请添加,然后进行更改)。
granadaCoder 2012年

更改视图比删除并重新创建视图更好。如果您有很多现有用户的视图安全设置,那您将不得不重新创建所有视图。这是我解决这个问题的方法。
jonas 2013年

您的CREATE和ALTER做不同的事情。(一个人是动态的,另一个人不是动态的,他们有不同的信息。)
Jay Sullivan

我感到困惑,您的CREATE VIEW语句如何涉及“被Alter语句替换”-这是什么意思?我也不清楚在这里实际上应该替换哪些代码,或者如何替换。我一定是您的答案感到困惑的少数人之一。
凯尔·朱丽(KyleJulé)2015年

2
对于SQL Server 2016 SP1 +,请参阅lad2025的答案。
MBWise

45

您可以使用“ IF EXISTS”检查视图是否存在,如果存在则删除视图。

如果存在(从INFORMATION_SCHEMA.VIEWS中选择TABLE_NAME
        WHERE TABLE_NAME ='MyView')
    拖放视图MyView
走

创建视图MyView
如 
     ....
走

13
这样做的问题是,您丢失了被删除对象上可能存在的所有权限。
simon

37

作为参考,SQL Server 2016 SP1+您可以使用CREATE OR ALTER VIEW语法。

MSDN创建视图

CREATE [ OR ALTER ] VIEW [ schema_name . ] view_name [ (column [ ,...n ] ) ]   
[ WITH <view_attribute> [ ,...n ] ]   
AS select_statement   
[ WITH CHECK OPTION ]   
[ ; ]

或更改

仅在视图已经存在时有条件地对其进行更改。

db <> fiddle演示


那是一种语法。您不能像在Oracle中那样同时使用CREATE和ALTER关键字。如果这样尝试,您将得到以下错误。-关键字“ OR”附近的语法不正确。-“ CREATE / ALTER PROCEDURE”必须是查询批处理中的第一条语句。
Div Tiwari

3
@DivTiwari,这显然在SQL 2016中有效。SQLServer仅用了11年的时间就赶上了此oracle功能,显然是:)
JosephStyons

1
@JosephStyons确实,您是对的!我不明白他们这么久以来如何错过这项重要功能。
Div Tiwari

@DivTiwari这是开发人员的选择:创建还是更改 迟到总比没有好:)
Lukasz Szozda

14

我用:

IF OBJECT_ID('[dbo].[myView]') IS NOT NULL
DROP VIEW [dbo].[myView]
GO
CREATE VIEW [dbo].[myView]
AS

...

最近,我为此类内容添加了一些实用程序:

CREATE PROCEDURE dbo.DropView
@ASchema VARCHAR(100),
@AView VARCHAR(100)
AS
BEGIN
  DECLARE @sql VARCHAR(1000);
  IF OBJECT_ID('[' + @ASchema + '].[' + @AView + ']') IS NOT NULL
  BEGIN
    SET @sql  = 'DROP VIEW ' + '[' + @ASchema + '].[' + @AView + '] ';
    EXEC(@sql);
  END 
END

所以现在我写

EXEC dbo.DropView 'mySchema', 'myView'
GO
CREATE View myView
...
GO

我认为这使我的变更脚本更具可读性


7

我通常使用这样的东西:

if exists (select * from dbo.sysobjects
  where id = object_id(N'dbo.MyView') and
  OBJECTPROPERTY(id, N'IsView') = 1)
drop view dbo.MyView
go
create view dbo.MyView [...]



2

您可以使用ALTER更新视图,但这不同于Oracle命令,因为它仅在视图已经存在时才起作用。借助DaveK的答案可能会更好,因为这将始终有效。


1
尽管ALTER保留了现有的权限(如果新版本存在语法错误等,则保留旧版本)。因此,使用IF NOT EXISTS ...创建一个Stub,然后使用ALTER替换它/原始可能会更好地维护权限和依赖项。
克里斯汀2009年

1

在SQL Server 2016(或更高版本)中,可以使用以下命令:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

在旧版本的SQL Server中,您必须使用类似

DECLARE @script NVARCHAR(MAX) = N'VIEW [dbo].[VW_NAMEOFVIEW] AS ...';

IF NOT EXISTS(SELECT * FROM sys.views WHERE name = 'VW_NAMEOFVIEW')
-- IF OBJECT_ID('[dbo].[VW_NAMEOFVIEW]') IS NOT NULL
BEGIN EXEC('CREATE ' + @script) END
ELSE
BEGIN EXEC('ALTER ' + @script) END

或者,如果视图上没有依赖项,则可以将其删除并重新创建:

IF EXISTS(SELECT * FROM sys.views WHERE name = 'VW_NAMEOFVIEW')
-- IF OBJECT_ID('[dbo].[VW_NAMEOFVIEW]') IS NOT NULL
BEGIN 
   DROP VIEW [VW_NAMEOFVIEW];
END

CREATE VIEW [VW_NAMEOFVIEW] AS ...

1
我正在使用SQL Server 2016(或更高版本),并且无法使用CREATE OR REPLACE VIEW语法。正确的语法是CREATE OR ALTER VIEW。怎么来了,这everybdody指出它是CREATE OR REPLACE在所有其他SO线程我发现🤔
WoIIe

@ Wolle,CREATE OR REPLACE是Oracle中的语法(请参见问题)
Eugene Lycenok
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.