SQL Server tương đương với CHẾ ĐỘ XEM TẠO HOẶC THAY THẾ của Oracle


115

Trong Oracle, tôi có thể tạo lại một khung nhìn bằng một câu lệnh duy nhất, như được hiển thị ở đây:

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

Như cú pháp ngụ ý, điều này sẽ loại bỏ chế độ xem cũ và tạo lại nó với bất kỳ định nghĩa nào tôi đã đưa ra.

Có phần mềm tương đương trong MSSQL (SQL Server 2005 trở lên) sẽ làm điều tương tự không?

Câu trả lời:


103

Mặc dù vậy, các giải pháp ở trên sẽ hoàn thành công việc nhưng có nguy cơ giảm quyền của người dùng. Tôi muốn tạo hoặc thay thế các chế độ xem hoặc các thủ tục được lưu trữ của mình như sau.

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
Tôi đã từng là người "Thả" rồi (lại) "Thêm". Nhưng bây giờ tôi nghiêng về loại giải pháp này (thêm nếu không có, sau đó thay đổi).
granadaCoder

Thay đổi một chế độ xem tốt hơn là thả và tạo lại nó. Điều gì xảy ra nếu bạn có nhiều thiết lập bảo mật người dùng hiện tại cho một chế độ xem, thì bạn sẽ phải tạo lại tất cả những người dùng đó. Đây là cách tiếp cận của tôi đối với vấn đề này.
jonas

CREATE và ALTER của bạn làm những việc khác nhau .... tại sao? (Một người thì năng động, người kia thì không, và họ có những thông điệp khác nhau.)
Jay Sullivan

Tôi thấy khó hiểu khi câu lệnh CREATE VIEW của bạn liên quan đến "được thay thế bằng một Câu lệnh thay thế" - điều đó có nghĩa là gì? Tôi cũng không rõ mã nào thực sự nên được thay thế ở đây, hoặc làm thế nào. Tôi phải là một trong số ít người bối rối trước câu trả lời của bạn.
Kyle Julé

2
Đối với SQL Server 2016 SP1 +, hãy xem câu trả lời của lad2025.
MBWise

45

Bạn có thể sử dụng 'NẾU TỒN TẠI' để kiểm tra xem chế độ xem có tồn tại hay không và giảm nếu có.

NẾU TỒN TẠI (CHỌN TABLE_NAME TỪ INFORMATION_SCHEMA.VIEWS
        WHERE TABLE_NAME = 'MyView')
    DROP XEM MyView
ĐI

TẠO XEM MyView
NHƯ 
     ....
ĐI

13
Vấn đề với điều này là bạn mất mọi quyền có thể đã tồn tại trên đối tượng đã bị loại bỏ.
simon

37

Để tham khảo từ SQL Server 2016 SP1+bạn có thể sử dụng CREATE OR ALTER VIEWcú pháp.

MSDN TẠO CHẾ ĐỘ XEM :

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

HOẶC THAY THẾ

Chỉ thay đổi chế độ xem có điều kiện nếu nó đã tồn tại.

db <> bản trình diễn fiddle


Đó là một cú pháp. Bạn không thể sử dụng cả hai từ khóa CREATE VÀ ALTER cùng một lúc như bạn làm trong ORACLE. bạn sẽ gặp lỗi dưới đây nếu cố gắng như thế này. - Cú pháp không chính xác gần từ khóa 'HOẶC'. - 'CREATE / ALTER PROCEDURE' phải là câu lệnh đầu tiên trong lô truy vấn.
Div Tiwari

3
@DivTiwari, đây là rõ ràng hợp lệ trong SQL 2016. Nó chỉ mất SQL Server 11 năm để bắt kịp với tính năng oracle này, rõ ràng :)
JosephStyons

1
@JosephStyons Thật vậy, bạn đã đúng! Tôi không hiểu làm thế nào mà họ lại bỏ lỡ một tính năng quan trọng như vậy lâu như vậy.
Div Tiwari

@DivTiwari Đó là Developers Choice: CREATE OR ALTER Muộn còn hơn không bao giờ :)
Lukasz Szozda

14

Tôi sử dụng:

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

...

Gần đây, tôi đã thêm một số thủ tục tiện ích cho loại nội dung này:

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

Vì vậy, bây giờ tôi viết

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

Tôi nghĩ nó làm cho các bản thay đổi của tôi dễ đọc hơn một chút


7

Tôi thường sử dụng một cái gì đó như thế này:

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 [...]


3

Nó hoạt động tốt đối với tôi trên SQL Server 2017:

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-


Cảm ơn bạn, điều này thật tuyệt. Tôi thấy rằng cú pháp này đã được giới thiệu trong SQL 2016. Khi tôi viết những câu hỏi, đó là cách trở lại trong SQL 2005.
JosephStyons

2

Bạn có thể sử dụng ALTER để cập nhật một dạng xem, nhưng lệnh này khác với lệnh Oracle vì nó chỉ hoạt động nếu dạng xem đã tồn tại. Có lẽ tốt hơn với câu trả lời của DaveK vì điều đó sẽ luôn hoạt động.


1
Mặc dù ALTER giữ các Quyền hiện có (và giữ lại Phiên bản cũ nếu phiên bản mới có lỗi cú pháp, v.v.). Vì vậy, sử dụng IF NOT EXISTS ... để tạo Stub và sau đó ALTER để thay thế nó / gốc có thể tốt hơn trong việc duy trì quyền và phụ thuộc.
Kristen

1

Trong SQL Server 2016 (hoặc mới hơn), bạn có thể sử dụng điều này:

CREATE OR ALTER VIEW VW_NAMEOFVIEW AS ...

Trong các phiên bản cũ hơn của máy chủ SQL, bạn phải sử dụng một số thứ như

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

Hoặc, nếu không có phụ thuộc vào chế độ xem, bạn chỉ có thể thả nó và tạo lại:

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
Tôi đang sử dụng SQL Server 2016 (hoặc mới hơn) và tôi không thể sử dụng CREATE OR REPLACE VIEWcú pháp. Cú pháp chính xác là CREATE OR ALTER VIEW. Tại sao, mọi người nói rằng nó nằm CREATE OR REPLACEtrong tất cả các chủ đề SO khác mà tôi tìm thấy 🤔
WoIIe

@Wolle, CREATE OR REPLACE là cú pháp trong Oracle (xem câu hỏi)
Eugene Lycenok
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.