Подтвердить что ты не робот

Невозможно использовать IF для создания или изменения вида в зависимости от вида existense

Я пытаюсь добиться того, что предлагает код ниже, но я получаю сообщение об ошибке 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 
4b9b3361

Ответ 1

Поскольку команды ALTER/CREATE не могут находиться в блоках BEGIN/END. Вам нужно проверить существование и отбросить его перед созданием

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

GO

CREATE VIEW TestView
   as
   . . .

GO

Если вы беспокоитесь о потерях разрешений, вы можете script сформулировать инструкции GRANT и повторно запустить их в конце.

Вы можете обернуть создание/изменение в строку и сделать 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)

Ответ 2

Я собирался прокомментировать ответ от ProfK, но не мог понять, как отформатировать код в комментарии, так что вот это ответ.


Использование sp_executesql лучше, но вам не нужно указывать его на nvarchar? В противном случае я получаю эту ошибку: процедура ожидает параметр '@statement' типа 'ntext/nchar/nvarchar'.

Вот что я использую в качестве шаблона вида:

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

Ответ 3

Уважаемый коллега помог мне в этом:

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

работает просто отлично.

Ответ 4

Вы должны отбросить представление, если оно было создано, а затем выполнить только изменение

IF OBJECT_ID('TestView') IS NOT NULL
BEGIN 

DROP VIEW TestView
END

GO

CREATE VIEW TestView

AS 

SELECT * FROM TestTable

Ответ 5

Рабочее и простое решение:

Просто оберните свой sql ключевым словом EXEC. Обратите внимание, что вам нужно только давать кавычки один раз, даже в многострочном 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

Ответ 6

Вот способ сделать это, чтобы избежать 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, поскольку вы теряете подсветку синтаксиса и разбор синтаксиса также не работает... Это также удобно, так как оно позволяет отказаться от просмотра. В моем случае представление используется в репликации, поэтому его отказ не выполняется, если репликация не удалена и не воссоздана.

Ответ 7

Если вы прочтете остальную часть сообщения об ошибке, он укажет, что создание представления должно быть первым утверждением или чем-то рядом с этими строками.

Try:

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

CREATE VIEW [dbo].[testView]
AS