SQL Server equivalente a CREATE OR REPLACE VIEW de Oracle

115

En Oracle, puedo volver a crear una vista con una sola declaración, como se muestra aquí:

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

Como implica la sintaxis, esto eliminará la vista anterior y la volverá a crear con la definición que le haya dado.

¿Existe un equivalente en MSSQL (SQL Server 2005 o posterior) que hará lo mismo?

JosephStyons
fuente

Respuestas:

103

Las soluciones anteriores, aunque harán el trabajo, lo hacen con el riesgo de perder los permisos de usuario. Prefiero crear o reemplazar vistas o procedimientos almacenados de la siguiente manera.

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
johndacostaa
fuente
2
Yo solía ser una persona "Drop" y luego (re) "Add". Pero ahora me inclino por este tipo de solución (agregue si no está allí, luego modifique).
granadaCoder
Modificar una vista es mucho mejor que soltarla y recrearla. ¿Qué sucede si tiene muchos usuarios configurados de seguridad para una vista? Entonces tendría que volver a crearlos todos. Este es mi enfoque de este problema.
jonas
Tu CREATE y ALTER hacen cosas diferentes ... ¿por qué? (Uno es dinámico, el otro no, y tienen diferentes mensajes).
Jay Sullivan
Me resulta confuso cómo su declaración CREATE VIEW implica "reemplazada por una declaración Alter" - ¿qué significa eso? Tampoco me queda claro qué código debería reemplazarse realmente aquí, o cómo. Debo ser uno de los pocos confundidos por tu respuesta.
Kyle Julé
2
Para SQL Server 2016 SP1 +, consulte la respuesta de lad2025.
MBWise
45

Puede usar 'SI EXISTE' para verificar si la vista existe y eliminar si existe.

SI EXISTE (SELECCIONE TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = 'MyView')
    VISTA GOTA MyView
VAMOS

CREAR VISTA MyView
COMO 
     ....
VAMOS
DaveK
fuente
13
El problema con esto es que pierde los permisos que puedan haber existido en el objeto que se eliminó.
Simon
37

Como referencia SQL Server 2016 SP1+, puede usar la CREATE OR ALTER VIEWsintaxis.

MSDN CREAR VISTA :

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

O ALTERAR

Altera condicionalmente la vista solo si ya existe.

db <> demostración de violín

Lukasz Szozda
fuente
Esa es una sintaxis. No puede usar las palabras clave CREAR Y ALTERAR al mismo tiempo como lo hace en ORACLE. obtendría los siguientes errores si lo intentara así. - Sintaxis incorrecta cerca de la palabra clave 'OR'. - 'CREAR / ALTERAR PROCEDIMIENTO' debe ser la primera instrucción en un lote de consultas.
Div Tiwari
3
@DivTiwari, esto aparentemente es válido en SQL 2016. A SQL Server solo le tomó 11 años ponerse al día con esta característica de
Oracle
1
@JosephStyons De hecho, ¡tienes razón! No entiendo cómo se perdieron una característica tan importante durante tanto tiempo.
Div Tiwari
@DivTiwari Fue la elección de los desarrolladores: CREAR O ALTERAR Mejor tarde que nunca :)
Lukasz Szozda
14

Yo suelo:

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

...

Recientemente agregué algunos procedimientos de utilidad para este tipo de cosas:

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

Entonces ahora escribo

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

Creo que hace que mis guiones de cambios sean un poco más legibles.

Tom
fuente
7

Normalmente uso algo como esto:

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
fuente
5

A partir de SQL Server 2016 tiene

DROP TABLE IF EXISTS [foo];

Fuente de MSDN

Justin Dearing
fuente
2

Puede usar ALTER para actualizar una vista, pero esto es diferente al comando de Oracle ya que solo funciona si la vista ya existe. Probablemente sea mejor con la respuesta de DaveK, ya que siempre funcionará.

Bryant
fuente
1
Aunque ALTER mantiene los permisos existentes (y conserva la versión anterior si la nueva versión tiene errores de sintaxis, etc.). Entonces, usar IF NOT EXISTS ... para crear un Stub, y luego ALTER para reemplazarlo / original puede ser mejor para mantener los permisos y las dependencias.
Kristen
1

En SQL Server 2016 (o más reciente) puede usar esto:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

En versiones anteriores del servidor SQL, debe usar algo como

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

O, si no hay dependencias en la vista, puede soltarla y volver a crear:

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
fuente
1
Estoy usando SQL Server 2016 (o más reciente) y no puedo usar la CREATE OR REPLACE VIEWsintaxis. La sintaxis correcta es CREATE OR ALTER VIEW. ¿Cómo es que todos dicen que está CREATE OR REPLACEen todos los demás subprocesos SO que encuentro?
WoIIe
@Wolle, CREATE OR REPLACE es la sintaxis en Oracle (ver la pregunta)
Eugene Lycenok