SQL Server equivalente a CREATE OR REPLACE VIEW da Oracle

115

No Oracle, posso recriar uma visualização com uma única instrução, conforme mostrado aqui:

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

Como a sintaxe indica, isso eliminará a visão antiga e a recriará com qualquer definição que eu tenha dado.

Existe um equivalente no MSSQL (SQL Server 2005 ou posterior) que fará a mesma coisa?

JosephStyons
fonte

Respostas:

103

As soluções acima, porém, farão o trabalho correr o risco de perder as permissões do usuário. Prefiro criar ou substituir visualizações ou procedimentos armazenados da seguinte maneira.

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
fonte
2
Eu costumava ser uma pessoa "Abandonar" e depois (re) "Adicionar". Mas agora me inclino para esse tipo de solução (acrescente, se não houver, altere).
granadaCoder
Alterar uma visualização é muito melhor do que descartá-la e recriá-la. E se você tiver muitos usuários existentes configurados de segurança para uma visualização, terá que recriar todos eles. Esta é a minha abordagem a este problema.
jonas
Seu CREATE e ALTER fazem coisas diferentes .... por quê? (Um é dinâmico, o outro não, e eles têm mensagens diferentes.)
Jay Sullivan
Acho confuso como a instrução CREATE VIEW envolve "substituído por uma instrução Alter" - o que isso significa? Também não está claro para mim qual código realmente deve ser substituído aqui, ou como. Devo ser um dos poucos confusos com sua resposta.
Kyle Julé
2
Para SQL Server 2016 SP1 +, consulte a resposta de lad2025.
MBWise de
45

Você pode usar 'IF EXISTS' para verificar se a visualização existe e descartá-la se existir.

SE EXISTE (SELECIONE TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = 'MyView')
    DROP VIEW MyView
IR

CRIAR VIEW MyView
COMO 
     ....
IR
DaveK
fonte
13
O problema com isso é que você perde todas as permissões que possam ter existido no objeto que foi descartado.
simon
37

Para referência, SQL Server 2016 SP1+você pode usar a CREATE OR ALTER VIEWsintaxe.

MSDN CREATE VIEW :

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

OU ALTER

Altera condicionalmente a exibição apenas se ela já existir.

db <> demonstração de violino

Lukasz Szozda
fonte
Essa é uma sintaxe. Você não pode usar as palavras-chave CREATE E ALTER ao mesmo tempo como faz no ORACLE. você obteria erros abaixo se tentasse assim. - Sintaxe incorreta perto da palavra-chave 'OU'. - 'CREATE / ALTER PROCEDURE' deve ser a primeira instrução em um lote de consultas.
Div Tiwari
3
@DivTiwari, isso é aparentemente válido no SQL 2016. O SQL Server levou apenas 11 anos para alcançar esse recurso do oráculo, aparentemente :)
JosephStyons
1
@JosephStyons Na verdade, você está correto! Não entendo como eles perderam um recurso tão importante por tanto tempo.
Div Tiwari
@DivTiwari Foi a escolha dos desenvolvedores: CRIAR OU ALTER Antes tarde do que nunca :)
Lukasz Szozda
14

Eu uso:

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

...

Recentemente, adicionei alguns procedimentos utilitários para esse tipo de coisa:

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

Então agora eu escrevo

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

Acho que torna meus scripts de mudança um pouco mais legíveis

Tom
fonte
7

Eu normalmente uso algo assim:

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

A partir do SQL Server 2016 você tem

DROP TABLE IF EXISTS [foo];

Fonte do MSDN

Justin Dearing
fonte
2

Você pode usar ALTER para atualizar uma visão, mas isso é diferente do comando Oracle, pois só funciona se a visão já existe. Provavelmente melhor com a resposta de DaveK, já que isso sempre funcionará.

Bryant
fonte
1
Embora ALTER mantenha as permissões existentes (e retém a versão antiga se a nova versão tiver erros de sintaxe etc.). Portanto, usar IF NOT EXISTS ... para criar um Stub e, em seguida, ALTER para substituí-lo / original pode ser melhor para manter as permissões e dependências.
Kristen
1

No SQL Server 2016 (ou mais recente), você pode usar isto:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

Em versões mais antigas do servidor SQL, você deve 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

Ou, se não houver dependências na visualização, você pode simplesmente descartá-la e recriar:

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
fonte
1
Estou usando o SQL Server 2016 (ou mais recente) e não consigo usar a CREATE OR REPLACE VIEWsintaxe. A sintaxe correta é CREATE OR ALTER VIEW. Como é, que todo mundo afirma que está CREATE OR REPLACEem todos os outros tópicos do SO que encontro 🤔
WoIIe
@Wolle, CREATE OR REPLACE é a sintaxe no Oracle (veja a pergunta)
Eugene Lycenok