120

In Oracle, I can re-create a view with a single statement, as shown here:

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

As the syntax implies, this will drop the old view and re-create it with whatever definition I've given.

Is there an equivalent in MSSQL (SQL Server 2005 or later) that will do the same thing?

Nickolay
  • 31,095
  • 13
  • 107
  • 185
JosephStyons
  • 57,317
  • 63
  • 160
  • 234

9 Answers9

107

The solutions above though they will get the job done do so at the risk of dropping user permissions. I prefer to do my create or replace views or stored procedures as follows.

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
john.da.costa
  • 4,682
  • 4
  • 29
  • 30
  • 2
    I used to be a "Drop" then (re) "Add" person. But now I lean to this type of solution (add if not there, then alter). – granadaCoder Aug 06 '12 at 13:44
  • Alter a view is way better than drop and recreate it. What if you have a lot of existing users security setup for a view, then you would have to recreate all those. This is my approach to this issue. – jonas Dec 04 '13 at 11:42
  • Your CREATE and ALTER do different things....why? (One's dynamic, the other's not, and they have different messages.) – Jay Sullivan Mar 12 '15 at 16:43
  • I find it confusing how your CREATE VIEW statement involves "replaced by an Alter Statement" - what does that mean? It's also not clear to me what code should actually be replaced here, or how. I must be one of the few confused by your answer. – Kyle Julé Mar 13 '15 at 20:55
  • Kyle that is just because a view definition cannot be empty. So all that is put there is a select 'x' as columnName. just to initialize the object if it does not exist. – john.da.costa Apr 22 '15 at 13:11
  • I use this approach too - and wrote a "create_stub" procedure to stub out the various types of objects I tend to create (views, procedures, functions). The idea is to create an idempotent maintenance script which does no harm if nothing changed. The "drop and create" approach drops user permissions as others have said, so might not be safe to rerun. – Kevin Olree Oct 27 '17 at 19:04
  • 2
    For SQL Server 2016 SP1+, see answer by lad2025. – MBWise Nov 15 '17 at 10:15
47

For reference from SQL Server 2016 SP1+ you could use CREATE OR ALTER VIEW syntax.

MSDN CREATE VIEW:

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

OR ALTER

Conditionally alters the view only if it already exists.

db<>fiddle demo

Community
  • 1
  • 1
Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
  • That's a syntax. You can not use both CREATE AND ALTER keywords at the same time like you do in ORACLE. you would get below errors if tried like this. - Incorrect syntax near the keyword 'OR'. - 'CREATE/ALTER PROCEDURE' must be the first statement in a query batch. – Mantra Mar 23 '17 at 11:15
  • 4
    @DivTiwari, this is apparently valid in SQL 2016. It only took SQL Server 11 years to catch up with this oracle feature, apparently :) – JosephStyons Nov 28 '17 at 05:12
  • 1
    @JosephStyons Indeed, you are correct ! I don't understand how did they miss such an important feature for so long. – Mantra Nov 28 '17 at 15:43
  • @DivTiwari It was [Developers Choice: CREATE OR ALTER](https://blogs.msdn.microsoft.com/sql_server_team/developers-choice-create-or-alter/) Better late than never :) – Lukasz Szozda Nov 28 '17 at 15:57
45

You can use 'IF EXISTS' to check if the view exists and drop if it does.

IF EXISTS (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = 'MyView')
    DROP VIEW MyView
GO

CREATE VIEW MyView
AS 
     ....
GO
DaveK
  • 4,509
  • 3
  • 33
  • 33
  • 13
    The problem with this is that you lose any permissions that may have existed on the object that got dropped. – simon Sep 14 '11 at 14:39
14

I use:

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

...

Recently I added some utility procedures for this kind of stuff:

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

So now I write

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

I think it makes my changescripts a bit more readable

Tom
  • 1,381
  • 3
  • 15
  • 26
8

I typically use something like this:

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 [...]
Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
8

As of SQL Server 2016 you have

DROP TABLE IF EXISTS [foo];

MSDN source

Justin Dearing
  • 14,270
  • 22
  • 88
  • 161
3

It works fine for me on SQL Server 2017:

USE MSSQLTipsDemo 
GO
CREATE OR ALTER PROC CreateOrAlterDemo
AS
BEGIN
SELECT TOP 10 * FROM [dbo].[CountryInfoNew]
END
GO

https://www.mssqltips.com/sqlservertip/4640/new-create-or-alter-statement-in-

Lex
  • 70
  • 3
  • Thank you, this is great. I see that this syntax was introduced in SQL 2016. When I wrote the question, it was way back in SQL 2005. – JosephStyons Nov 20 '17 at 18:36
3

In SQL Server 2016 (or newer) you can use this:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

In older versions of SQL server you have to use something like

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

Or, if there are no dependencies on the view, you can just drop it and recreate:

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 ...
MovGP0
  • 7,267
  • 3
  • 49
  • 42
  • 1
    I am using SQL Server 2016 (or newer) and I cannot use `CREATE OR REPLACE VIEW` syntax. The correct syntax is `CREATE OR ALTER VIEW`. How comes, that everybdody states it is `CREATE OR REPLACE` in every other SO thread I find – ˈvɔlə Nov 20 '19 at 15:13
  • @Wolle, CREATE OR REPLACE is the syntax in Oracle (see the question) – Eugene Lycenok Jun 16 '20 at 02:18
2

You can use ALTER to update a view, but this is different than the Oracle command since it only works if the view already exists. Probably better off with DaveK's answer since that will always work.

Bryant
  • 8,660
  • 1
  • 33
  • 53
  • 1
    Although ALTER keeps existing Permissions (and retains the Old Version if the new version has syntax errors etc.). So using IF NOT EXISTS ... to create a Stub, and then ALTER to replace it/original may be better in maintaining permissions and dependencies. – Kristen Feb 24 '09 at 20:07