【问题标题】:Deletion\Creation of Temp tables in SQL Server 2008在 SQL Server 2008 中删除\创建临时表
【发布时间】:2013-12-30 14:50:19
【问题描述】:

我有这样的 SQL 代码

IF Object_id('tempdb..#empDate) IS NOT NULL
  DROP TABLE #empDate
CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )

在上面的代码之后还有几行SQL,然后重复。

我收到以下错误。

消息 2714,第 16 层,状态 1,第 589 行
数据库中已经有一个名为“#empDate”的对象。

我换了

IF Object_id('tempdb..#empDate) IS NOT NULL

IF Object_id('tempdb..#empDate%) IS NOT NULL

正如论坛上写的那样,SQL Server 会将数字附加到后续的临时表中。

来源: Check if a temporary table exists and delete if it exists before creating a temporary table

http://blog.sqlauthority.com/2009/05/17/sql-server-how-to-drop-temp-table-check-existence-of-temp-table/

http://blog.sqlauthority.com/2009/03/29/sql-server-fix-error-msg-2714-level-16-state-6-there-is-already-an-object-named-temp-in-the-database/

我在 Windows 7 Enterprise 上使用 Microsoft SQL Server 2008。

我无法理解错误的原因。

请帮忙。

【问题讨论】:

  • If EXISTS(Select * From tempdb.dbo.sysobjects Where ID = OBJECT_ID(N'tempdb..#empDate')) Begin Drop Table #empDate End
  • 为什么要检查表是否存在两次?如果您在同一会话中创建它,您就知道它存在。你只是使用了一个本地临时表,所以它不会受到其他会话的影响,只需跳过第二条 create table 语句,或者按照 M Ali 的建议执行并分批运行。
  • 你为什么不在这里给出一个正确的问题标题? “SQL Server 2008 中的临时表” 对我来说实际上不是问题!
  • @huMptyduMpty :现在标题还好吗?
  • @user2560781:​​似乎比以前好多了:)。但不要在标题上包含标签,即sql-server 2008。请阅读Should questions include “tags” in their titles?

标签: sql sql-server sql-server-2008


【解决方案1】:

示例一

这将失败...... 再次执行相同的代码,会抛出你现在得到的错误

IF Object_id('tempdb..#empDate') IS NOT NULL
 BEGIN
  DROP TABLE #empDate
 END 

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )


IF Object_id('tempdb..#empDate') IS NOT NULL
 BEGIN
  DROP TABLE #empDate
 END 

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )

示例二(固定)

IF Object_id('tempdb..#empDate') IS NOT NULL
 BEGIN
  DROP TABLE #empDate
 END 

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )

GO      --<-- Adding this Batch Separator will eliminate the Error

IF Object_id('tempdb..#empDate') IS NOT NULL
 BEGIN
  DROP TABLE #empDate
 END 

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )

测试

如果您尝试一次性执行以下语句,即使根本没有任何名称为#empDate 的表,它们也会失败,它甚至不会执行第一个创建表语句。并且会抛出错误。

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )


DROP TABLE #empDate


CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )

但是如果你将所有语句分成不同的批次,它们将像这样成功执行..

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )
GO

DROP TABLE #empDate
GO

CREATE TABLE #empDate
  (
     [empID]   INT,
     [AddLoc] VARCHAR(1000)
  )
GO

【讨论】:

  • 没问题,很高兴它有帮助。
【解决方案2】:

我会直接放弃你的桌子而不做任何预先检查。

然后干净地编写/运行脚本。

使用临时表完成后,将其放在脚本末尾。

所以无条件运行这个

DROP TABLE #empDate

然后编写/运行您的脚本,并确保您的脚本末尾有这一行。

【讨论】:

    【解决方案3】:

    使用 object_id 传递数据库名称

    示例:

    DECLARE @db_id int;
    DECLARE @object_id int;
    SET @db_id = DB_ID(N'AdventureWorks2012');
    SET @object_id = OBJECT_ID(N'AdventureWorks2012.Person.Address');
    IF @db_id IS NULL 
    BEGIN;
    PRINT N'Invalid database';
    END;
    ELSE IF @object_id IS NULL
    BEGIN;
    PRINT N'Invalid object';
    END;
    ELSE
    BEGIN;
    SELECT * FROM sys.dm_db_index_operational_stats(@db_id, @object_id, NULL, NULL);
    END;
    GO
    

    【讨论】: