SQL Server équivalent à CREATE OR REPLACE VIEW d'Oracle

115

Dans Oracle, je peux recréer une vue avec une seule instruction, comme indiqué ici:

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

Comme la syntaxe l'indique, cela supprimera l'ancienne vue et la recréera avec la définition que j'ai donnée.

Existe-t-il un équivalent dans MSSQL (SQL Server 2005 ou version ultérieure) qui fera la même chose?

JosephStyons
la source

Réponses:

103

Les solutions ci-dessus, bien qu'elles feront le travail, le font au risque de supprimer les autorisations des utilisateurs. Je préfère créer ou remplacer des vues ou des procédures stockées comme suit.

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
la source
2
J'étais une personne "Drop" puis (re) "Add". Mais maintenant je me penche sur ce type de solution (ajouter si ce n'est pas là, puis modifier).
granadaCoder
Modifier une vue est bien mieux que de la supprimer et de la recréer. Que se passe-t-il si vous avez beaucoup de paramètres de sécurité d'utilisateurs existants pour une vue, alors vous devriez recréer tout cela. Telle est mon approche de cette question.
jonas
Votre CREATE et ALTER font des choses différentes .... pourquoi? (L'un est dynamique, l'autre pas, et ils ont des messages différents.)
Jay Sullivan
Je trouve déroutant comment votre instruction CREATE VIEW implique "remplacé par une instruction Alter" - qu'est-ce que cela signifie? Je ne sais pas non plus quel code devrait réellement être remplacé ici, ni comment. Je dois être l'un des rares à être confus par votre réponse.
Kyle Julé
2
Pour SQL Server 2016 SP1 +, consultez la réponse de lad2025.
MBWise
45

Vous pouvez utiliser «IF EXISTS» pour vérifier si la vue existe et la supprimer si elle existe.

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

CRÉER UNE VUE MyView
COMME 
     ....
ALLER
DaveK
la source
13
Le problème avec cela est que vous perdez toutes les autorisations qui auraient pu exister sur l'objet qui a été supprimé.
simon le
37

Pour référence, SQL Server 2016 SP1+vous pouvez utiliser la CREATE OR ALTER VIEWsyntaxe.

MSDN CREATE VIEW :

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

OU MODIFIER

Modifie conditionnellement la vue uniquement si elle existe déjà.

démo db <> fiddle

Lukasz Szozda
la source
C'est une syntaxe. Vous ne pouvez pas utiliser les mots clés CREATE ET ALTER en même temps comme vous le faites dans ORACLE. vous obtiendrez des erreurs ci-dessous si vous essayiez comme ça. - Syntaxe incorrecte à côté du mot-clé «OU». - 'CREATE / ALTER PROCEDURE' doit être la première instruction d'un lot de requêtes.
Div Tiwari
3
@DivTiwari, cela est apparemment valide dans SQL 2016. Il n'a fallu que 11 ans à SQL Server pour rattraper cette fonctionnalité d'oracle, apparemment :)
JosephStyons
1
@JosephStyons En effet, vous avez raison! Je ne comprends pas comment ils ont raté une fonctionnalité aussi importante pendant si longtemps.
Div Tiwari
@DivTiwari C'était le choix des développeurs: CRÉER OU MODIFIER Mieux vaut tard que jamais :)
Lukasz Szozda
14

J'utilise:

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

...

Récemment, j'ai ajouté des procédures utilitaires pour ce genre de choses:

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

Alors maintenant j'écris

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

Je pense que cela rend mes scripts de modification un peu plus lisibles

À M
la source
7

J'utilise généralement quelque chose comme ceci:

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
la source
5

Depuis SQL Server 2016, vous avez

DROP TABLE IF EXISTS [foo];

Source MSDN

Justin Dearing
la source
2

Vous pouvez utiliser ALTER pour mettre à jour une vue, mais ceci est différent de la commande Oracle car elle ne fonctionne que si la vue existe déjà. Probablement mieux avec la réponse de DaveK car cela fonctionnera toujours.

Bryant
la source
1
Bien qu'ALTER conserve les autorisations existantes (et conserve l'ancienne version si la nouvelle version comporte des erreurs de syntaxe, etc.). Donc, utiliser IF NOT EXISTS ... pour créer un stub, puis ALTER pour le remplacer / original peut être préférable pour maintenir les autorisations et les dépendances.
Kristen
1

Dans SQL Server 2016 (ou plus récent), vous pouvez utiliser ceci:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

Dans les anciennes versions du serveur SQL, vous devez utiliser quelque chose comme

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, s'il n'y a pas de dépendances sur la vue, vous pouvez simplement la supprimer et la recréer:

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
la source
1
J'utilise SQL Server 2016 (ou plus récent) et je ne peux pas utiliser la CREATE OR REPLACE VIEWsyntaxe. La syntaxe correcte est CREATE OR ALTER VIEW. Comment se fait-il, que chaque corps déclare que c'est CREATE OR REPLACEdans tous les autres fils SO que je trouve 🤔
WoIIe
@Wolle, CREATE OR REPLACE est la syntaxe d'Oracle (voir la question)
Eugene Lycenok