Невозможно использовать 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
Ответы
Ответ 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