如何使SQL Server中的CREATE或REPLACE VIEW工作?

Ale*_*lex 31 sql sql-server porting view

CREATE OR REPLACE VIEW似乎在SQL Server中不起作用.那么我如何移植CREATE OR REPLACE VIEW到SQL Server上?

这就是我想要做的:

CREATE OR REPLACE VIEW data_VVVV AS 
SELECT 
    VCV.xxxx,
        VCV.yyyy AS yyyy,
        VCV.zzzz AS zzzz
FROM 
TABLE_A
;
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

JaK*_*KXz 66

借用@Khan的答案,我会这样做:

IF OBJECT_ID('dbo.test_abc_def', 'V') IS NOT NULL
    DROP VIEW dbo.test_abc_def
GO

CREATE VIEW dbo.test_abc_def AS
SELECT 
    VCV.xxxx
    ,VCV.yyyy AS yyyy
    ,VCV.zzzz AS zzzz
FROM TABLE_A
Run Code Online (Sandbox Code Playgroud)

MSDN参考

  • `DROP`和后面的`CREATE`将删除元数据,例如授予的权限.在您不是SA的SQL Server中,这可能非常糟糕...... (9认同)
  • 在 Oracle 中,“创建或替换”是原子的,因此没有停机时间,即使在应用程序想要查询视图时,您也可以毫无问题地更新视图。 (2认同)

Gor*_*off 41

这是另一种方法,您不必复制视图的内容:

IF (NOT EXISTS (SELECT 1 FROM sys.views WHERE name = 'data_VVV'))
BEGIN
    EXECUTE('CREATE VIEW data_VVVV as SELECT 1 as t');
END;

GO

ALTER VIEW data_VVVV AS 
    SELECT VCV.xxxx, VCV.yyyy AS yyyy, VCV.zzzz AS zzzz FROM TABLE_A ;
Run Code Online (Sandbox Code Playgroud)

第一个检查是否存在视图(还有其他方法可以做到这一点).如果它不存在,那么用简单和愚蠢的东西创建它.如果是,那么继续前进到alter view声明.

  • 多年来,我一直将这种方法用于视图/过程。它还维护分配给它们的任何特殊安全性。DROP 失去了这一点。 (3认同)
  • 这似乎不起作用.SQL Server抱怨CREATE VIEW必须是一批语句中的第一行.下面的答案首先使视图失效. (2认同)
  • 如果不同模式中存在同名视图怎么办?为了涵盖这种情况,可以使用“SELECT 1 FROM INFORMATION_SCHEMA.VIEWS WHERE table_name = 'data_VVV' AND table_schema = 'dbo'”来代替“SELECT 1 FROM sys.views WHERE name = 'data_VVV'” (2认同)

Muh*_*eed 24

SQL Server 2016答案

使用SQL Server 2016,您现在可以执行(MSDN源代码):

DROP VIEW IF EXISTS dbo.MyView
Run Code Online (Sandbox Code Playgroud)

  • 并根据[另一个答案](/sf/answers/2849520551/),也"创建或更改视图"! (5认同)

Kha*_*han 13

编辑:虽然这个问题已被标记为重复,但它仍然受到关注.@JaKXz提供的答案是正确的,应该是接受的答案.


您需要检查视图是否存在.然后做一个CREATE VIEWALTER VIEW取决于结果.

IF OBJECT_ID('dbo.data_VVVV') IS NULL
BEGIN
    CREATE VIEW dbo.data_VVVV
    AS
    SELECT VCV.xxxx, VCV.yyyy AS yyyy, VCV.zzzz AS zzzz FROM TABLE_A VCV
END
ELSE
    ALTER VIEW dbo.data_VVVV
    AS
    SELECT VCV.xxxx, VCV.yyyy AS yyyy, VCV.zzzz AS zzzz FROM TABLE_A VCV
BEGIN
END
Run Code Online (Sandbox Code Playgroud)

  • 这在SQL Server中不起作用."创建视图"必须是批处理中的第一个,当试图将其放入"IF"时,我会在关键字"VIEW"附近得到"不正确的语法". (39认同)
  • 如今,您可以在 **SQL Server 2016+** 中使用“CREATE OR ALTER VIEW” (5认同)
  • 任何人都可以提供一个答案,为什么CREATE VIEW必须是批处理中唯一的语句但允许CREATE TABLE? (3认同)
  • 这会导致您重复选择语句,因此您必须考虑的代码量确实增加了一倍。下面的 JaKXz 回答是更好的方法 (2认同)
  • 您必须将CREATE语句包装到EXEC('your create statement')中。否则,它将无法在IF中使用。 (2认同)

sta*_*ler 8

已接受的解决方案存在需要两次维护相同语句的问题,它不是非常有效(尽管它有效).从理论上讲,Gordon Linoff的解决方案将会解决,除非它在MSSQL中不起作用,因为创建视图必须是批处理中的第一行.

drop/create不会回答提出的问题.以下是原始问题的工作.

if not exists (select * from sysobjects where name='TABLE_A' and xtype='V')
exec ('create view SELECT 
VCV.xxxx,
    VCV.yyyy AS yyyy,
    VCV.zzzz AS zzzz
FROM TABLE_A')
Run Code Online (Sandbox Code Playgroud)