如何正确检查SQL Server 2005中是否存在临时表?

Sna*_*yes 28 sql sql-server sql-server-2005

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

SELECT ID, NAME INTO #tmpTable1
FROM TableOriginal
Run Code Online (Sandbox Code Playgroud)

首次执行没问题,如果我在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
Run Code Online (Sandbox Code Playgroud)

不工作,错误再次显示如上.

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

dbo.#tmpTable1__________________0000007
Run Code Online (Sandbox Code Playgroud)

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

如何删除现有临时表以使用新值执行新表?

mar*_*c_s 54

你很近 - 你需要在支票中使用两个点:

IF OBJECT_ID('tempdb..#tmpTable1') IS NOT NULL  
                    ** 
                    |
                  use two dots here!
Run Code Online (Sandbox Code Playgroud)

基本上,这是说:检查tempDB并且我不关心表中的模式

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

IF OBJECT_ID('tempdb.dbo.#tmpTable1') IS NOT NULL  
Run Code Online (Sandbox Code Playgroud)

如果您碰巧在默认所有者以外的架构中创建对象,则需要明确指定您所指的架构.但临时表tempDB确实在dbo模式中创建.

  • @marc_s:我认为,...(双点)转移到默认所有者,即dbo (2认同)

Aar*_*and 11

这不是一个问题的答案,只是想暂时张贴有关puting到比特的响应.dbo...引用#TEMP表时.

我找不到让#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%';
Run Code Online (Sandbox Code Playgroud)

结果:

-1222354987    -1222354987    -1222354987

-1222354987    dbo
Run Code Online (Sandbox Code Playgroud)

这是在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);
Run Code Online (Sandbox Code Playgroud)

结果:

消息2714,级别16,状态6
数据库中已存在名为"#flab"的对象.

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

所以,这是一种冗长的说法,你不需要在解析#temp表名时指定模式,它总是在下创建dbo,至少在解析下OBJECT_ID将忽略你指定的模式(OBJECT_SCHEMA_NAME也总是dbo在#tempdb的上下文中运行时返回,但不在任何其他数据库中运行.如果您尝试查询schema_id,则所有投注均已关闭tempdb.sys.objects.