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

时间:2009-03-10 21:14:19

标签: sql-server

我正在尝试实现下面代码所示的内容,但我在create和alter行上都收到了错误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 

7 个答案:

答案 0 :(得分:19)

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

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

GO

CREATE VIEW TestView
   as
   . . .

GO

如果您担心丢失权限,您也可以编写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)

答案 1 :(得分: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

答案 2 :(得分:5)

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

if object_id('demoView') is null
    sp_executesql 'create view demoView as select * from demoTable'

工作得很好。

答案 3 :(得分:3)

工作&简单的解决方案:

使用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

答案 4 :(得分:1)

如果视图已创建,则应删除该视图,然后仅执行更改

IF OBJECT_ID('TestView') IS NOT NULL
BEGIN 

DROP VIEW TestView
END

GO

CREATE VIEW TestView

AS 

SELECT * FROM TestTable

答案 5 :(得分:0)

这是一种避免sp_execute_sql

的方法
    IF EXISTS ( SELECT  1
                FROM    sysobjects
                WHERE   type = 'V'
                        AND name = 'vwTradeEventTemp' )
        BEGIN
            DROP VIEW [dbo].[vwTradeEventTemp];
        END;
    GO

    CREATE VIEW [dbo].[vwTradeEventTemp]
    WITH SCHEMABINDING
    AS
    select col1, col2 from table
IF NOT EXISTS ( SELECT  1
                FROM    sysobjects
                WHERE   type = 'V'
                        AND name = 'vwTradeEvent' )
        BEGIN
            PRINT 'vwTradeEvent does not exist, renaming vwTradeEventTemp to vwTradeEvent to work around not being able to check for view existence before creating';
            EXEC sp_rename @objname = 'vwTradeEventTemp',
                @newname = 'vwTradeEvent', @objtype = 'object';
        END;
    ELSE
        BEGIN
            PRINT 'vwTradeEvent already exists, dropping vwTradeEventTemp';
            DROP VIEW dbo.vwTradeEventTemp;
        END;

我不喜欢使用sp_executesql,因为你失去了语法突出显示和解析也没有工作......这也很方便,因为它避免了丢弃视图。在我的情况下,视图用于复制,因此除非删除并重新创建复制,否则删除它将失败。

答案 6 :(得分:-1)

如果您阅读了错误消息的其余部分,则会指出创建视图必须是第一个语句或其他内容。

尝试:

IF  EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[testView]'))
    DROP VIEW [dbo].[testView]
GO

CREATE VIEW [dbo].[testView]
AS