【问题标题】:Drop view if exists如果存在则删除视图
【发布时间】:2016-07-08 02:55:43
【问题描述】:

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

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

【问题讨论】:

  • 在这些命令之间放置一个GO...
  • 我把它放在创建之前:Go Create....等但后来得到:数据库中已经有一个名为'TSB'的对象。
  • 错误的对象类型 - 使用“V”而不是“U”。 msdn.microsoft.com/en-us/library/ms190324.aspx
  • 是的,已更改并且正在运行

标签: sql sql-server view create-view


【解决方案1】:

您的存在语法错误,您应该使用 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

【讨论】:

  • 谢谢,将 U 更改为 V,现在可以使用了!感谢您的帮助
  • 轻微修正 - DROP VIEW dbo.tst IF EXISTS 应改为 DROP VIEW IF EXISTS dbo.tst
  • 谢谢,我实际上在 go after drop 后面有一个分号,但它不喜欢这样。删除了分号,它工作得很好。
  • 如何将架构添加到检查中?
【解决方案2】:

关于错误

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

Microsoft SQL Server 有一个奇怪的要求,即CREATE VIEW 是批处理中的only 语句。其他一些语句也是如此,例如CREATE FUNCTIONCREATE TABLE 的情况不是正确的,所以去想一想……

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

更方便的解决方案是让客户端分小批发送脚本。

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

因此,您最终会编写如下内容:

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

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

【讨论】:

    【解决方案3】:

    为了满足架构的需要,请在 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
    

    【讨论】:

      【解决方案4】:
      DROP VIEW if exists {ViewName}
      Go
      CREATE View {ViewName} AS 
      SELECT * from {TableName}  
      Go
      

      【讨论】:

        猜你喜欢
        • 2020-01-11
        • 1970-01-01
        • 1970-01-01
        • 2014-12-24
        • 1970-01-01
        • 1970-01-01
        • 2013-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多