SQL Server equivalente a CREATE OR REPLACE VIEW di Oracle


115

In Oracle, posso ricreare una vista con una singola istruzione, come mostrato qui:

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

Come suggerisce la sintassi, questo eliminerà la vecchia vista e la ricrea con qualsiasi definizione che ho dato.

Esiste un equivalente in MSSQL (SQL Server 2005 o successivo) che farà la stessa cosa?

Risposte:


103

Le soluzioni di cui sopra, sebbene porteranno a termine il lavoro, lo fanno a rischio di far cadere le autorizzazioni dell'utente. Preferisco creare o sostituire visualizzazioni o stored procedure come segue.

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
Ero una persona "Drop" e poi (ri) "Add". Ma ora mi appoggio a questo tipo di soluzione (aggiungi se non c'è, quindi modifica).
granadaCoder

Modificare una vista è molto meglio che rilasciarla e ricrearla. E se hai molti utenti esistenti per la configurazione della sicurezza per una vista, dovresti ricrearli tutti. Questo è il mio approccio a questo problema.
jonas

Il tuo CREATE e ALTER fanno cose diverse .... perché? (Uno è dinamico, l'altro no, e hanno messaggi diversi.)
Jay Sullivan

Trovo confuso il modo in cui la tua istruzione CREATE VIEW implica "sostituito da un'istruzione Alter" - cosa significa? Inoltre non mi è chiaro quale codice debba essere effettivamente sostituito qui o come. Devo essere uno dei pochi confusi dalla tua risposta.
Kyle Julé

2
Per SQL Server 2016 SP1 +, vedere la risposta di lad2025.
MBWise

45

Puoi utilizzare "SE ESISTE" per verificare se la visualizzazione esiste e rilasciarla se esiste.

SE ESISTE (SELEZIONA NOME TABELLA DA INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = "MyView")
    VISTA DROP MyView
PARTIRE

CREA VISTA MyView
COME 
     ....
PARTIRE

13
Il problema con questo è che perdi tutte le autorizzazioni che potrebbero essere esistite sull'oggetto che è stato rilasciato.
simon

37

Per riferimento SQL Server 2016 SP1+potresti usare la CREATE OR ALTER VIEWsintassi.

MSDN CREATE VIEW :

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

O ALTER

Modifica in modo condizionale la visualizzazione solo se esiste già.

db <> fiddle demo


Questa è una sintassi. Non è possibile utilizzare contemporaneamente le parole chiave CREATE E ALTER come si fa in ORACLE. si otterrebbero errori di seguito se provati in questo modo. - Sintassi non corretta vicino alla parola chiave "OR". - "CREATE / ALTER PROCEDURE" deve essere la prima istruzione in un batch di query.
Div Tiwari

3
@DivTiwari, questo è apparentemente valido in SQL 2016. Ci sono voluti solo 11 anni per SQL Server per raggiungere questa funzionalità di Oracle, apparentemente :)
JosephStyons

1
@JosephStyons In effetti, hai ragione! Non capisco come abbiano fatto a perdere una caratteristica così importante per così tanto tempo.
Div Tiwari

@DivTiwari È stata la scelta degli sviluppatori: CREARE O MODIFICARE Meglio tardi che mai :)
Lukasz Szozda

14

Io uso:

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

...

Recentemente ho aggiunto alcune procedure di utilità per questo tipo di cose:

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

Quindi ora scrivo

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

Penso che renda i miei script di modifica un po 'più leggibili


7

Di solito uso qualcosa del genere:

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

È possibile utilizzare ALTER per aggiornare una vista, ma questo è diverso dal comando Oracle poiché funziona solo se la vista esiste già. Probabilmente è meglio con la risposta di DaveK poiché funzionerà sempre.


1
Sebbene ALTER mantenga le autorizzazioni esistenti (e conserva la vecchia versione se la nuova versione ha errori di sintassi ecc.). Quindi usare IF NOT EXISTS ... per creare uno Stub, e poi ALTER per sostituirlo / original potrebbe essere migliore per mantenere i permessi e le dipendenze.
Kristen

1

In SQL Server 2016 (o più recente) puoi usare questo:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

Nelle versioni precedenti di SQL Server devi usare qualcosa di simile

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

Oppure, se non ci sono dipendenze dalla vista, puoi semplicemente rilasciarla e ricreare:

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
Sto usando SQL Server 2016 (o più recente) e non riesco a usare la CREATE OR REPLACE VIEWsintassi. La sintassi corretta è CREATE OR ALTER VIEW. Come mai CREATE OR REPLACEogni corpo afferma che è in ogni altro thread SO che trovo 🤔
WoIIe

@Wolle, CREATE OR REPLACE è la sintassi in Oracle (vedere la domanda)
Eugene Lycenok,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.