如果存在的话如何删除表?


721

表名是Scores

执行以下操作是否正确?

IF EXISTS(SELECT *
          FROM   dbo.Scores)
  DROP TABLE dbo.Scores

Answers:


1376

执行以下操作是否正确?

IF EXISTS(SELECT *
          FROM   dbo.Scores)
  DROP TABLE dbo.Scores

。仅当表包含任何行时,它才会删除表(如果表不存在,则会引发错误)。

相反,对于永久表,您可以使用

IF OBJECT_ID('dbo.Scores', 'U') IS NOT NULL 
  DROP TABLE dbo.Scores; 

或者,对于临时表,您可以使用

IF OBJECT_ID('tempdb.dbo.#T', 'U') IS NOT NULL
  DROP TABLE #T; 

使用SQL Server 2016+有更好的方法DROP TABLE IF EXISTS …。请参阅@Jovan的答案


137
Fwiw- 'U'第二个参数显然意味着“仅查找具有此名称的表对象”。 一个来源。所以,OBJECT_ID('TableName')是不是错的,但它不是出奇的准确要么,从而'U'在@马丁的出色答卷。
鲁芬

7
关于第二个参数;这是另一个来源,我使用“ V”表示视图。
红豌豆

4
嗨,您能解释一下第二个参数在OBJECT_ID('tempdb.dbo。#T','U')中的含义吗,例如这个'U'吗?
Zvonimir Tokic'2

9
@ZvonimirTokic表示“用户定义表”。“ IT”将是内部的,系统定义的表。完整列表在此处msdn.microsoft.com/zh-cn/library/ms190324.aspx
Martin Smith,


151

ANSI SQL /跨平台方法是使用INFORMATION_SCHEMA,该信息是专门设计用于查询有关SQL数据库中对象的元数据。

if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'Scores' AND TABLE_SCHEMA = 'dbo')
    drop table dbo.Scores;

大多数现代RDBMS服务器至少提供基本的INFORMATION_SCHEMA支持,包括:MySQLPostgresOracleIBM DB2Microsoft SQL Server 7.0(及更高版本)


if existsANSI兼容?
马丁·史密斯

8
如果数据库中有多个模式,请当心。您可能需要具体说明要检测和删除的[分数]。例如,其中TABLE_NAME = '分数' AND TABLE_SCHEMA = 'DBO'
安德鲁延

@kiquenet通常是,但是在使用if存在时不这样做-因为一旦返回一行,它就会停止。但是我个人总是选择1。
哈拉格2015年

68

已经看到了很多不起作用的东西。创建临时表时,必须将其从tempdb中删除!

唯一有效的代码是:

IF OBJECT_ID('tempdb..#tempdbname') IS NOT NULL     --Remove dbo here 
    DROP TABLE #tempdbname   -- Remoeve "tempdb.dbo"

3
谢谢,进行了更改dbotempdb使这项工作生效。我还建议添加'u'接受的答案的评论中提到的。因此,完整的IF语句应如下所示:IF OBJECT_ID('tempdb..#temp', 'U')
whiteshooz

38

在SQL Server 2016(13.x)及更高版本中

DROP TABLE IF EXISTS dbo.Scores

在早期版本中

IF OBJECT_ID('dbo.Scores', 'U') IS NOT NULL 
DROP TABLE dbo.Scores; 

是你的table type


28

要么:

if exists (select * from sys.objects where name = 'Scores' and type = 'u')
    drop table Scores

4
自2005年起,您就可以使用sys.tables简化此操作:if exists (select * from sys.tables where name = 'Scores') drop table Scores
Michael Parker

26

我希望这有帮助:

begin try drop table #tempTable end try
begin catch end catch

22

我编写了一个小UDF,如果其参数是现存表的名称,则返回1,否则返回0:

CREATE FUNCTION [dbo].[Table_exists]
(
    @TableName VARCHAR(200)
)
    RETURNS BIT
AS
BEGIN
    If Exists(select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = @TableName)
        RETURN 1;

    RETURN 0;
END

GO

要删除表(User如果存在),请像这样调用它:

IF [dbo].[Table_exists]('User') = 1 Drop table [User]

相同名称但不同架构的情况如何?最好的方法是在这里:stackoverflow.com/a/33497857/956364
毗邻的



4

我用:

if exists (select * 
           from sys.tables 
           where name = 'tableName' 
           and schema_id = schema_id('dbo'))
begin
    drop table dbo.tableName
end


-1

如果您使用的是Visual Studio,则可以通过一种更好的视觉和简便方法,只需从菜单栏中打开,

查看-> SQL Server对象资源管理器

它应该像这里显示的那样打开

在此处输入图片说明

选择并右键单击要删除的表,然后删除。应该显示这样的屏幕。单击更新数据库进行确认。

在此处输入图片说明

此方法非常安全,因为它可以为您提供反馈,并会警告已删除表与其他表的任何关系。


5
这个问题是有关的SQL,而不是有关的Visual Studio。因此,这个答案与这个问题无关。
阿德南·谢里夫

-8

这样做,这是最简单的方法。

qry 将是您自己的查询,无论您在选择列表中想要什么。

set @qry = ' select * into TempData from (' + @qry + ')Tmp  '

exec (@qry)

select * from TempData 

drop table TempData

4
只是我,还是看起来容易注射?请评论。
g00dy

5
它也与问题无关
Martin Smith
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.