33

我有一个查询,我从表中插入一些值:

SELECT ID, NAME INTO #tmpTable1
FROM TableOriginal

第一次执行没问题,如果我在 MSSMS(Microsoft Sql Server Management Studio)中按 F5(运行),就会出现错误:

消息 2714,级别 16,状态 6,第 4 行
数据库中已经有一个名为“#tmpTable1”的对象。

好的。我决定在插入数据之前检查TableOriginal一下#tmpTable1

IF OBJECT_ID('tempdb.#tmpTable1') IS NOT NULL  
  DROP TABLE #tmpTable1

不起作用,错误再次显示如上。

我在tempdb数据库中看到以下临时表名:

dbo.#tmpTable1__________________0000007

为什么?每次创建临时表(使用第一个查询)时,表名会在 MSSMS 中自动生成?

如何删除现有的临时表以创建具有新值的新表?

4

5 回答 5

61

您非常接近 - 您需要在支票中使用两个点:

IF OBJECT_ID('tempdb..#tmpTable1') IS NOT NULL  
                    ** 
                    |
                  use two dots here!

基本上,这就是说:签入tempDB并且我不在乎表在什么模式中

正如乔正确地说:这不是 100% 正确的:它不会检查每个模式 - 它只会检查默认所有者的模式 - 通常dbo。所以这也可以:

IF OBJECT_ID('tempdb.dbo.#tmpTable1') IS NOT NULL  

如果您碰巧在默认所有者以外的模式中创建对象,那么您需要明确指定您所指的模式。但是其中的临时表tempDB确实是在dbo模式中创建的。

于 2012-08-16T11:57:58.853 回答
12

这不是问题的答案,只是想在引用#temp 表时临时发布关于放置.dbo.与放置的位的回复。..

我找不到让#temp 表实际上归dbo 以外的任何人所有的方法。试试看:

CREATE SCHEMA blat;
GO

CREATE TABLE blat.#pound(id INT);
GO

SELECT 
   OBJECT_ID('tempdb..#pound'), 
   OBJECT_ID('tempdb.dbo.#pound'), 
   OBJECT_ID('tempdb.blat.#pound');

USE tempdb;
GO

SELECT [object_id], SCHEMA_NAME([schema_id]) 
  FROM sys.objects 
  WHERE name LIKE '#pound%';

结果:

-1222354987    -1222354987    -1222354987

-1222354987    dbo

这是在 SQL Server 2012 上。我在 SQL Server 2005 上进行了测试,唯一的区别是 object_id 值为正。我也尝试过:

  • tempdb 中实际存在的架构称为blat
  • blat.#pound由默认架构为的用户创建的表blat
  • 以上两者

在所有三种情况下,都获得了与上述相同的结果。

您也不能在不同的架构中创建两个具有相同名称的 #temp 表:

CREATE TABLE blat.#flab(id INT);
CREATE TABLE dbo.#flab(id INT);

结果:

消息 2714,级别 16,状态 6
数据库中已经有一个名为“#flab”的对象。

这不是解析问题(就像许多#temp 表问题一样);您可以分别运行这两个语句并收到相同的错误。

因此,这是一种冗长的说法,在解析#temp 表名时,您永远不需要指定架构,它将始终在下面创建dbo并且解析至少在下面OBJECT_ID将忽略您指定的架构(OBJECT_SCHEMA_NAME也总是在#tempdb 的上下文中运行时返回dbo,但不在任何其他数据库中)。如果您尝试schema_idtempdb.sys.objects.

于 2012-08-16T12:43:30.857 回答
2
CREATE TABLE #temptable (col1 int);
GO
INSERT INTO #temptable
VALUES (10);
GO
SELECT * FROM #temptable;
GO
IF OBJECT_ID(N'tempdb..#temptable', N'U') IS NOT NULL 
DROP TABLE #temptable;
GO
--Test the drop.
SELECT * FROM #temptable;
于 2015-05-11T09:23:57.243 回答
-1

只要创建它的连接打开,以这种方式定义的临时表就会存在。通常不需要检查它是否存在或手动删除它,因为你可以完全控制你的连接,但如果你真的需要检查它,你可以检查 tempdb.dbo.#tempTable。

于 2012-08-16T12:03:59.050 回答
-1

如果 OBJECT_ID('tempdb.dbo.#tmpTable1%') 不为 NULL :)

于 2015-02-02T20:58:22.930 回答