65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Server 2016 中的 DROP IF EXISTS

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (5投票s)

2016年10月2日

CPOL

3分钟阅读

viewsIcon

14355

在 SQL Server 2016 中删除对象时,检查其存在性的增强功能

引言

通过这个非常小但实用的技巧,我们将检查 SQL Server 2016 中对 DROP 语句所做的增强。 以前,我们通常编写额外的检查逻辑来确保对象存在才能删除。 如果我们忽略了检查,并且对象不可用,那么就会收到一条错误消息。 使用 SQL Server 2016,现在我们可以在不生成任何错误的情况下检查相应对象是否存在。

检查的必要性

对于那些不经常使用 DROP 语句的人来说,最明显的问题可能是 - "在执行 DROP 语句之前,我真的需要检查对象是否存在吗?"
嗯,答案是肯定的。
为什么? 让我们快速测试一下,看看结果如何。 执行以下语句之一

--(1)
DROP Database ARandomDatabaseForDemo
GO

--(2)
DROP TABLE ARandomTableForDemo
GO

--(3)
DROP PROCEDURE ARandomProcForDemo
GO

--(4)
DROP FUNCTION ARandomFunctionForDemo
GO

--(5)
DROP TRIGGER ARandomTriggerForDemo
GO

--Note: Execute only if you don't have the respective objects

它将立即抛出一个异常,如下所示

无法删除数据库/表/存储过程/函数/触发器 'ARandom[Database/Table/Procedure/Function/Trigger]ForDemo',因为它不存在或您没有权限。

现在在另一种情况下,假设我们有一个表,但没有我们想要删除的列或任何属性/约束。

ALTER TABLE [dbo].[Registration] DROP COLUMN AnyColumn  
GO

我们会收到一条错误消息,例如

ALTER TABLE DROP COLUMN 失败,因为表 'Registration' 中不存在列 'AnyColumn'。

在大多数情况下,我们可能不希望收到错误消息。 我们宁愿跳过错误消息并继续执行脚本中的其余逻辑。 一个非常常见的例子是,当我们想要在数据库中创建一个表时,我们通常会检查该特定数据库中是否存在该表,如果存在,我们会删除它并使用最新的结构创建该表。 这种情况通常出现在我们处于开发或设计数据库的初始阶段,并且多个资源在同一个项目上工作时。

旧方法

以前,我们编写了一个很长的 IF EXISTS 语句来检查相应的对象是否存在,然后是 DROP 语句。

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = _
OBJECT_ID(N'[dbo].[ARandomTableForDemo]') AND type in (N'U'))
DROP TABLE [dbo].[ARandomTableForDemo]
GO

或者

IF OBJECT_ID('[dbo].[ARandomTableForDemo]', 'U') IS NOT NULL
DROP TABLE [dbo].[ARandomTableForDemo]
GO

新的、更简单、更好的方法

让我们使用新的语法重写 DROP 语句。

语法

DROP DATABASE [ IF EXISTS ] database_name

示例

DROP DATABASE IF EXISTS ARandomDatabaseForDemo
GO

这难道不是很简单直接吗?

让我们看看我们编写的 DROP 语句的完整列表,这些语句没有检查是否存在,通过应用新的 DROP IF EXISTS 方法。

--(1) 
DROP Database IF EXISTS ARandomDatabaseForDemo
GO

--(2) 
DROP TABLE IF EXISTS ARandomTableForDemo
GO

--(3) 
DROP PROCEDURE IF EXISTS ARandomProcForDemo
GO

--(4) 
DROP FUNCTION IF EXISTS ARandomFunctionForDemo
GO

--(5) 
DROP TRIGGER IF EXISTS ARandomTriggerForDemo
GO 

如果您想 DROP 一列或约束,您可以这样做

ALTER TABLE [dbo].[Registration] DROP COLUMN IF EXISTS AnyColumn GO

与其他竞争对手的比较

MySQL:MySQL 已经提供了这种功能,可以在 DROP 语句中包含此可选子句。

DROP [TEMPORARY] TABLE [IF EXISTS]
    tbl_name [, tbl_name] ...
    [RESTRICT | CASCADE]

参考:https://dev.mysqlserver.cn/doc/refman/5.7/en/drop-table.html

PostgreSQL:PostgreSQL 也有相同的功能。

DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]

参考:https://postgresql.ac.cn/docs/8.2/static/sql-droptable.html

Oracle:到目前为止,还没有这样的选项。 我已经检查了文档,但找不到任何提及。 因此,选项是

  • DROP 之前检查对象是否存在
  • 捕获异常并处理

结论

这确实是 SQL Server 2016 数据定义语言 (DDL) 功能列表的一个很好的补充。 如果您觉得此技巧有帮助,请分享您的反馈。

历史

  • 2016 年 10 月 2 日:首次发布
© . All rights reserved.