41

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

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' 必须是查询批处理中的第一条语句。

4

4 回答 4

104

你存在的语法是错误的,你应该用 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
于 2016-03-21T14:38:38.680 回答
4

关于错误

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

Microsoft SQL Server 有一个奇怪的要求,即批处理CREATE VIEW中的唯一语句。这也适用于其他一些语句,例如CREATE FUNCTION. 事实并非如此CREATE TABLE,所以去想一想……</p>

解决方案是将您的脚本小批量发送到服务器。一种方法是选择一条语句并执行它。这显然很不方便。

更方便的解决方案是让客户端以独立的小批量发送脚本。

关键字不是严格意义上的GOSQL 命令,这就是为什么不能像真正的 SQL 命令那样用分号结束它的原因。相反,它是指示客户端在此时中断脚本并将该部分作为批处理发送。

结果,您最终会编写如下内容:

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

我遇到的其他数据库服务器(PostgreSQL、MySQL、Oracle、SQLite)都没有这个怪癖,所以要求似乎是 Microsoft Only。

于 2018-11-24T22:11:59.767 回答
3
DROP VIEW if exists {ViewName}
Go
CREATE View {ViewName} AS 
SELECT * from {TableName}  
Go
于 2019-04-18T08:39:19.693 回答
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
于 2018-05-01T22:05:59.433 回答