SQL Server odpowiednik widoku CREATE OR REPLACE VIEW firmy Oracle

115

W Oracle mogę odtworzyć widok za pomocą jednej instrukcji, jak pokazano tutaj:

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

Jak sugeruje składnia, spowoduje to usunięcie starego widoku i ponowne utworzenie go z dowolną definicją, którą podałem.

Czy istnieje odpowiednik w MSSQL (SQL Server 2005 lub nowszy), który zrobi to samo?

JosephStyons
źródło

Odpowiedzi:

103

Jednak powyższe rozwiązania wykonają swoją pracę, ryzykując utratę uprawnień użytkownika. Wolę tworzyć lub zamieniać widoki lub procedury składowane w następujący sposób.

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
źródło
2
Kiedyś byłem osobą „Upuść”, a następnie (ponownie) „Dodaj”. Ale teraz skłaniam się do tego typu rozwiązania (dodaj, jeśli nie tam, to zmień).
granadaCoder
Zmiana widoku jest o wiele lepsza niż upuszczenie i odtworzenie go. A co, jeśli masz wielu istniejących ustawień bezpieczeństwa użytkowników dla widoku, musisz je wszystkie odtworzyć. Takie jest moje podejście do tej kwestii.
jonas
Twoje CREATE i ALTER robią różne rzeczy… dlaczego? (Jeden jest dynamiczny, drugi nie, i mają różne przesłania.)
Jay Sullivan
Wydaje mi się mylące, jak twoja instrukcja CREATE VIEW jest „zastąpiona przez instrukcję Alter” - co to oznacza? Nie jest też dla mnie jasne, który kod powinien zostać tutaj zastąpiony lub jak. Muszę być jednym z nielicznych zdezorientowanych twoją odpowiedzią.
Kyle Julé
2
W przypadku programu SQL Server 2016 z dodatkiem SP1 + zobacz odpowiedź lad2025.
MBWise
45

Możesz użyć opcji „JEŚLI ISTNIEJE”, aby sprawdzić, czy widok istnieje, i porzucić, jeśli tak.

JEŚLI ISTNIEJE (WYBIERZ NAZWĘ TABELI Z INFORMACJE_SCHEMA.WIDOKÓW
        WHERE TABLE_NAME = „MyView”)
    DROP VIEW MyView
UDAĆ SIĘ

UTWÓRZ WIDOK MyView
TAK JAK 
     ....
UDAĆ SIĘ
DaveK
źródło
13
Problem polega na tym, że tracisz wszelkie uprawnienia, które mogły istnieć dla upuszczonego obiektu.
simon
37

W celach informacyjnych SQL Server 2016 SP1+możesz użyć CREATE OR ALTER VIEWskładni.

WIDOK UTWÓRZ MSDN :

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

LUB ZMIENIĆ

Warunkowo zmienia widok tylko wtedy, gdy już istnieje.

db <> fiddle demo

Łukasz Szozda
źródło
To jest składnia. Nie możesz używać jednocześnie słów kluczowych UTWÓRZ I ZMIEŃ, tak jak w ORACLE. jeśli spróbujesz w ten sposób, otrzymasz poniższe błędy. - Niepoprawna składnia w pobliżu słowa kluczowego „OR”. - „UTWÓRZ / ZMIEN PROCEDURĘ” musi być pierwszą instrukcją w partii zapytania.
Div Tiwari
3
@DivTiwari, jest to najwyraźniej poprawne w SQL 2016. Najwyraźniej SQL Server potrzebował tylko 11 lat, aby dogonić tę funkcję wyroczni :)
JosephStyons
1
@JosephStyons Rzeczywiście, masz rację! Nie rozumiem, dlaczego tak długo przegapili tak ważną funkcję.
Div Tiwari
@DivTiwari To był wybór deweloperów: UTWÓRZ LUB ZMIENIA Lepiej późno niż wcale :)
Lukasz Szozda
14

Używam:

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

...

Ostatnio dodałem kilka narzędzi do tego typu rzeczy:

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

Więc teraz piszę

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

Myślę, że dzięki temu moje skrypty zmian są bardziej czytelne

Tomek
źródło
7

Zwykle używam czegoś takiego:

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
źródło
5

Od SQL Server 2016 masz

DROP TABLE IF EXISTS [foo];

Źródło MSDN

Justin Dearing
źródło
2

Możesz użyć ALTER, aby zaktualizować widok, ale różni się to od polecenia Oracle, ponieważ działa tylko wtedy, gdy widok już istnieje. Prawdopodobnie lepiej będzie z odpowiedzią DaveK, ponieważ to zawsze zadziała.

Bryant
źródło
1
Chociaż ALTER zachowuje istniejące uprawnienia (i zachowuje starą wersję, jeśli nowa wersja zawiera błędy składniowe itp.). Więc użycie JEŚLI NIE ISTNIEJE ... do utworzenia Stub, a następnie ALTER, aby zamienić go / oryginał, może być lepsze w utrzymaniu uprawnień i zależności.
Kristen
1

W SQL Server 2016 (lub nowszym) możesz użyć tego:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

W starszych wersjach serwera SQL musisz użyć czegoś takiego jak

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

Lub, jeśli nie ma żadnych zależności w widoku, możesz go po prostu upuścić i odtworzyć:

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
źródło
1
Używam programu SQL Server 2016 (lub nowszego) i nie mogę używać CREATE OR REPLACE VIEWskładni. Prawidłowa składnia to CREATE OR ALTER VIEW. Jak to się dzieje, że wszyscy twierdzą, że jest CREATE OR REPLACEw każdym innym SO wątku, który znajduję 🤔
WoIIe
@Wolle, CREATE OR REPLACE to składnia w Oracle (zobacz pytanie)
Eugene Lycenok