我正在尝试实现下面代码所示的内容,但我在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
答案 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