使用 OBJECT_ID() 的“如果不存在”不适用于视图和触发器。为什么?

SHR*_*SHR 6 trigger sql-server view

对于表,我可以实现“如果不存在”和“如果存在”如下:

--if table exists - drop
If OBJECT_ID('A','U') is not null
Drop Table [A]
--if table not exists - Create
If OBJECT_ID('A','U') is null
Create Table A([key] varchar(20), [value] varchar(max))
Run Code Online (Sandbox Code Playgroud)

但它在视图和触发器上的作用并不完全相同

我可以:

-- if exists - drop
If OBJECT_ID('VA','V') is not null
Drop view [VA]
Run Code Online (Sandbox Code Playgroud)

但是当我尝试相反的时候:

-- if not exists - create
If OBJECT_ID('VA','V') is null
Create view [VA] as Select * from [A] 
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

关键字“view”附近的语法不正确

触发器也是如此。当我做:

-- if not exists - create
If OBJECT_ID('Trigger_A_ins','TR') is null
Create trigger [Trigger_A_ins] On [A] instead of insert As 
   insert into A select * from inserted
Run Code Online (Sandbox Code Playgroud)

我收到错误:

关键字 'trigger' 附近的语法不正确

但:

-- if exists - drop
If OBJECT_ID('Trigger_A_ins','TR') is not null
Drop Trigger Trigger_A_ins
Run Code Online (Sandbox Code Playgroud)

正在工作。

我错过了什么吗?

任何人都可以解释表与触发器和视图之间的区别吗?

注意:我使用的是 sql server 2012

Sco*_*red 11

参考REMARKS 下CREATE VIEW 中的文档:

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

参考CREATE TRIGGER 中的文档

CREATE TRIGGER 必须是批处理中的第一条语句,并且只能应用于一个表。

对于VIEWSand TRIGGERS,我认为您必须检查对象是否存在并放入一批中,然后在另一批中创建它们,以GO

例子:

IF EXISTS (SELECT * FROM sys.objects WHERE [name] = '[dbo].[trg]' AND [type] = 'TR')
      DROP TRIGGER [dbo].[trg] ON [dbo].[tbl]
GO
CREATE TRIGGER [dbo].[trg] ON [dbo].[tbl] 
AFTER DELETE
AS
BEGIN
   //
END
GO
Run Code Online (Sandbox Code Playgroud)


EzL*_*zLo 7

如果您在同一批次上仍需要此功能,则可以使用动态 SQL。

If OBJECT_ID('vTest','V') is not null
    DROP VIEW vTest

EXEC('CREATE VIEW vTest AS SELECT TOP 1 * FROM SomeTable')
Run Code Online (Sandbox Code Playgroud)