根据视图的存在性,不能使用IF来创建或更改视图

Pro*_*ofK 14 sql-server

我正在尝试实现下面的代码建议,但我Incorrect syntax near the keyword 'view'在创建和更改行上都收到错误.

IF Object_ID('TestView') IS NULL
    BEGIN
        create view TestView
        as
        . . .
    END
ELSE
    BEGIN
        ALTER view TestView
        as
        . . .   
    END 
Run Code Online (Sandbox Code Playgroud)

DJ.*_*DJ. 20

因为ALTER/CREATE命令不能在BEGIN/END块内.您需要测试是否存在并在创建之前删除它

IF Object_ID('TestView') IS NOT NULL
    DROP VIEW TestView

GO

CREATE VIEW TestView
   as
   . . .

GO
Run Code Online (Sandbox Code Playgroud)

如果您担心丢失权限,您也可以编写GRANT语句的脚本,并在最后重新运行它们.

你可以将create/alter包装成一个字符串并执行EXEC - 这对于大型视图来说可能会很难看

DECLARE @SQL as varchar(4000)

-- set to body of view
SET @SQL = 'SELECT X, Y, Z FROM TABLE' 

IF Object_ID('TestView') IS NULL
    SET @SQL = 'CREATE VIEW TestView AS ' + @SQL
ELSE    
    SET @SQL = 'ALTER VIEW TestView AS ' + @SQL

EXEC(@SQL)
Run Code Online (Sandbox Code Playgroud)

  • 删除视图而不是更改视图会丢失视图上的权限设置. (3认同)
  • 这是不正确的.在将新表设计引入数据库时​​,我一直使用带有create table语句的Begin end块. (2认同)

Syl*_*via 10

我打算对ProfK的答案发表评论,但是无法弄清楚如何在评论中格式化代码,所以这里是一个答案.


使用sp_executesql更好,但是你不需要指出它是一个nvarchar吗?否则我收到此错误:过程需要'ntext/nchar/nvarchar'类型的参数'@statement'.

这是我用作视图模板的内容:

If not exists (Select Table_Name from INFORMATION_SCHEMA.VIEWS where Table_Name = 'vMessage') begin 
    exec sp_executesql N'create view vMessage as select test = 1'
    print 'Creating view vMessage'
end 

print 'Altering view vMessage'
go
Alter view vMessage 
as
Select 
* 
from Message
Run Code Online (Sandbox Code Playgroud)


Pro*_*ofK 5

一位受人尊敬的同事帮助了我:

if object_id('demoView') is null
    sp_executesql 'create view demoView as select * from demoTable'
Run Code Online (Sandbox Code Playgroud)

工作得很好.


Zbi*_*dro 5

工作和简单的解决方案:

只需用 EXEC 关键字包装您的 sql 即可。请注意,即使在多行 sql 中,您也只需给出一次引号:

IF NOT EXISTS(select * FROM sys.views where name = 'TestView')
  BEGIN    
    EXEC ('
      CREATE VIEW [dbo].[TestView]
      AS
        SELECT
          *
        FROM
          dbo.SomeTable
    ')
  END
ELSE
  BEGIN
    EXEC ('
      ALTER VIEW [dbo].[TestView]
      AS
        SELECT
          *
        FROM
          dbo.SomeTable
    ')
  END
Run Code Online (Sandbox Code Playgroud)