SQL Server entspricht der CREATE OR REPLACE VIEW von Oracle

115

In Oracle kann ich eine Ansicht mit einer einzelnen Anweisung neu erstellen, wie hier gezeigt:

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

Wie aus der Syntax hervorgeht, wird die alte Ansicht gelöscht und mit der von mir angegebenen Definition neu erstellt.

Gibt es in MSSQL (SQL Server 2005 oder höher) ein Äquivalent, das dasselbe tut?

JosephStyons
quelle

Antworten:

103

Bei den oben genannten Lösungen besteht jedoch die Gefahr, dass Benutzerberechtigungen gelöscht werden. Ich ziehe es vor, Ansichten oder gespeicherte Prozeduren wie folgt zu erstellen oder zu ersetzen.

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
quelle
2
Ich war früher eine "Drop" - und dann (wieder) "Add" -Person. Aber jetzt lehne ich mich an diese Art von Lösung (füge hinzu, wenn nicht da, dann ändere).
GranadaCoder
Eine Ansicht zu ändern ist viel besser als sie zu löschen und neu zu erstellen. Was ist, wenn Sie viele Sicherheitseinstellungen für eine Ansicht für vorhandene Benutzer haben, dann müssen Sie alle diese neu erstellen. Dies ist meine Herangehensweise an dieses Problem.
Jonas
Dein CREATE und ALTER machen verschiedene Dinge ... warum? (Einer ist dynamisch, der andere nicht, und sie haben unterschiedliche Botschaften.)
Jay Sullivan
Ich finde es verwirrend, wie Ihre CREATE VIEW-Anweisung "durch eine Alter-Anweisung ersetzt" beinhaltet - was bedeutet das? Mir ist auch nicht klar, welcher Code hier eigentlich ersetzt werden soll oder wie. Ich muss einer der wenigen sein, die durch Ihre Antwort verwirrt sind.
Kyle Julé
2
Informationen zu SQL Server 2016 SP1 + finden Sie unter Antwort von lad2025.
MBWise
45

Mit 'IF EXISTS' können Sie überprüfen, ob die Ansicht vorhanden ist, und sie löschen, wenn dies der Fall ist.

WENN EXISTIERT (SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = 'MyView')
    DROP VIEW MyView
GEHEN

ANSICHT ERSTELLEN MyView
WIE 
     ....
GEHEN
DaveK
quelle
13
Das Problem dabei ist, dass Sie alle Berechtigungen verlieren, die möglicherweise für das Objekt vorhanden waren, das gelöscht wurde.
Simon
37

Als Referenz können SQL Server 2016 SP1+Sie die CREATE OR ALTER VIEWSyntax verwenden.

MSDN CREATE VIEW :

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

ODER ÄNDERN

Ändert die Ansicht nur bedingt, wenn sie bereits vorhanden ist.

db <> Geigen-Demo

Lukasz Szozda
quelle
Das ist eine Syntax. Sie können nicht wie in ORACLE gleichzeitig die Schlüsselwörter CREATE AND ALTER verwenden. Sie würden unter Fehler kommen, wenn Sie dies versuchen. - Falsche Syntax in der Nähe des Schlüsselworts 'OR'. - 'CREATE / ALTER PROCEDURE' muss die erste Anweisung in einem Abfragebatch sein.
Div Tiwari
3
@ DivTiwari, dies ist anscheinend in SQL 2016 gültig. SQL Server hat anscheinend nur 11 Jahre gebraucht, um diese Orakel-Funktion
nachzuholen
1
@ JosephStyons In der Tat sind Sie richtig! Ich verstehe nicht, wie sie so lange ein so wichtiges Feature verpasst haben.
Div Tiwari
@ DivTiwari Es war die Wahl der Entwickler: ERSTELLEN ODER ÄNDERN Besser spät als nie :)
Lukasz Szozda
14

Ich benutze:

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

...

Kürzlich habe ich einige Dienstprogrammverfahren für diese Art von Sachen hinzugefügt:

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

Also schreibe ich jetzt

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

Ich denke, das macht meine Änderungsskripte ein bisschen lesbarer

Tom
quelle
7

Ich benutze normalerweise so etwas:

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

Ab SQL Server 2016 haben Sie

DROP TABLE IF EXISTS [foo];

MSDN-Quelle

Justin Dearing
quelle
3

Unter SQL Server 2017 funktioniert es einwandfrei:

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
quelle
Danke, das ist großartig. Ich sehe, dass diese Syntax in SQL 2016 eingeführt wurde. Als ich die Frage schrieb, war es weit zurück in SQL 2005.
JosephStyons
2

Sie können ALTER verwenden, um eine Ansicht zu aktualisieren. Dies unterscheidet sich jedoch vom Oracle-Befehl, da er nur funktioniert, wenn die Ansicht bereits vorhanden ist. Wahrscheinlich besser dran mit DaveKs Antwort, da das immer funktionieren wird.

Bryant
quelle
1
Obwohl ALTER vorhandene Berechtigungen beibehält (und die alte Version beibehält, wenn die neue Version Syntaxfehler usw. aufweist). Wenn Sie also IF NOT EXISTS ... verwenden, um einen Stub zu erstellen, und dann ALTER, um ihn / original zu ersetzen, können Sie möglicherweise Berechtigungen und Abhängigkeiten besser beibehalten.
Kristen
1

In SQL Server 2016 (oder neuer) können Sie Folgendes verwenden:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

In älteren Versionen von SQL Server müssen Sie so etwas wie verwenden

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

Wenn die Ansicht keine Abhängigkeiten enthält, können Sie sie einfach löschen und neu erstellen:

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
quelle
1
Ich verwende SQL Server 2016 (oder neuer) und kann keine CREATE OR REPLACE VIEWSyntax verwenden. Die richtige Syntax lautet CREATE OR ALTER VIEW. Wie kommt es, dass jeder sagt, dass es CREATE OR REPLACEin jedem anderen SO-Thread ist, den ich finde Wo
WoIIe
@Wolle, CREATE OR REPLACE ist die Syntax in Oracle (siehe Frage)
Eugene Lycenok