如果存在则删除视图

59

我有一个脚本,我想先删除视图,然后再创建它。 我知道如何删除表:

我想在脚本中先删除视图,然后再创建它。我知道如何删除表:

IF EXISTS (SELECT * FROM sys.tables WHERE name = 'table1' AND type = 'U') DROP TABLE table1;

于是我对视图也做了同样的操作:

IF EXISTS (SELECT * FROM sys.views WHERE name = 'view1' AND type = 'U') DROP VIEW view1;
create view1 as(......)

然后我遇到了错误:

'CREATE VIEW'必须是查询批处理中的第一条语句。


1
在这些命令之间放置一个 GO - Shnugo
我把它放在创建之前:Go Create....等等,但是后来出现了这个错误:数据库中已经存在一个名为“TSB”的对象。 - 4est
3
对象类型错误-请使用'V'代替'U'。https://msdn.microsoft.com/zh-cn/library/ms190324.aspx - Ivan Starostin
是的,已经更改并且正在运行。 - 4est
4个回答

124

您的存在语法错误,您应该像下面这样用go分隔DDL

if exists(select 1 from sys.views where name='tst' and type='v')
drop view tst;
go

create view tst
as
select * from test

您也可以使用以下类似的 object_id 进行存在性测试

if object_id('tst','v') is not null
drop view tst;
go

create view tst
as
select * from test
在SQL 2016中,您可以使用以下语法来删除。
Drop view  if exists dbo.tst

从SQL2016 CU1开始,您可以执行以下操作

create or alter view vwTest
as
 select 1 as col;
go

2
谢谢,将U改为V,现在可以工作了!感谢帮助。 - 4est
1
小修正 - DROP VIEW dbo.tst IF EXISTS 应该改为 DROP VIEW IF EXISTS dbo.tst。 - Rich
1
谢谢,实际上我在"drop"之后加了一个分号,导致它不喜欢。移除分号之后,它完美地工作了。 - natur3
如何将模式添加到检查中? - user230910

4
DROP VIEW if exists {ViewName}
Go
CREATE View {ViewName} AS 
SELECT * from {TableName}  
Go

4

关于错误信息

'CREATE VIEW' must be the first statement in a query batch.

微软SQL Server有一个古怪的要求,即CREATE VIEW必须是批处理中的唯一语句。这也适用于其他一些语句,例如CREATE FUNCTION。但对于CREATE TABLE则不是这样,令人费解……

解决方法是将脚本分成小批次发送到服务器。一种方法是选择单个语句并执行它。这显然很不方便。

更方便的解决方法是让客户端将脚本分成小的隔离批次发送。

GO关键字不是严格意义上的SQL命令,这就是为什么您不能像真正的SQL命令一样以分号结尾。相反,它是一条指令,告诉客户端在此处中断脚本,并将该部分作为批处理发送。

因此,您最终会编写类似以下内容的代码:

DROP VIEW IF EXISTS … ;
GO
CREATE VIEWAS … ;
GO

在我遇到的其他数据库服务器中(PostgreSQL、MySQL、Oracle、SQLite),都没有这个怪癖,因此这种要求似乎只适用于 Microsoft。


2
为了适应模式,可以在SQL 2014中使用以下格式。
if exists(select 1 from sys.views V inner join sys.[schemas] S on  v.schema_id = s.schema_id where s.name='dbo' and v.name = 'someviewname' and v.type = 'v')
  drop view [dbo].[someviewname];
go

仅仅提一下,如果需要执行存储过程,可以像我一样使用以下方法:

if exists(select 1
          from sys.procedures p
          inner join sys.[schemas] S on p.schema_id = s.schema_id
          where
              s.name='dbo' and p.name = 'someprocname'
          and p.type in ('p', 'pc')
  drop procedure [dbo].[someprocname];
go

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接