简体   繁体   English

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

[英]How to check correctly if a temporary table exists in SQL Server 2005?

I have a query where I insert some values from a table: 我有一个查询,我从表中插入一些值:

SELECT ID, NAME INTO #tmpTable1
FROM TableOriginal

First execution is fine, if I press F5(Run) in MSSMS (Microsoft Sql Server Management Studio), the error occured: 首次执行没问题,如果我在MSSMS(Microsoft Sql Server Management Studio)中按F5(运行),则会发生错误:

Msg 2714, Level 16, State 6, Line 4 Msg 2714,Level 16,State 6,Line 4
There is already an object named '#tmpTable1' in the database. 数据库中已经有一个名为“#tmpTable1”的对象。

Good. 好。 I decided to check before insert data from TableOriginal to #tmpTable1 using: 我决定在使用以下方法将TableOriginal数据插入#tmpTable1之前进行检查:

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

Not working, the error shows again as above. 不工作,错误再次显示如上。

I saw in tempdb database the following temporary table name: 我在tempdb数据库中看到了以下临时表名:

dbo.#tmpTable1__________________0000007

Why? 为什么? Every time when create a temporary table (using first query), the table name will be generated automatically in MSSMS ? 每次创建临时表(使用第一个查询)时,表名都将在MSSMS中自动生成?

How to remove the existing temporary table to do a new table with new values ? 如何删除现有临时表以使用新值执行新表?

You're darn close - you need to use two dots in your check: 你很近 - 你需要在支票中使用两个点:

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

Basically, this is saying: check in the tempDB and I don't care what schema the table is in 基本上,这是说: 检查tempDB ,我不关心表中的模式

As Joe rightfully said: this is not 100% correct: it doesn't check in every schema - it will only check in the default owner's schema - normally dbo . 正如Joe所说:这不是100%正确:它不会检查每个模式 - 它只会检查默认所有者的模式 - 通常是dbo So this would work, too: 所以这也可行:

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

If you happen to create your objects in a schema other than the default owner's, then you'll need to explicitly specify the schema you're referring to. 如果您碰巧在默认所有者以外的架构中创建对象,则需要明确指定您所指的架构。 But the temp tables in tempDB are indeed creating in the dbo schema. 但是tempDB中的临时表确实是在dbo模式中创建的。

This isn't an answer to the question, just wanted to temporarily post a response to the bit about puting .dbo. 这不是问题的答案,只是想暂时发布关于.dbo. vs. .. when referencing a #temp table. vs. ..引用#temp表时。

I couldn't find a way to make a #temp table actually be owned by anything other than dbo. 我找不到让#temp表实际上由除dbo以外的任何东西所拥有的方法。 Try it: 试试吧:

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%';

Results: 结果:

-1222354987    -1222354987    -1222354987

-1222354987    dbo

This was on SQL Server 2012. I tested this on SQL Server 2005 and the only difference was the object_id values were positive. 这是在SQL Server 2012上。我在SQL Server 2005上进行了测试,唯一的区别是object_id值为正。 I also tried with: 我也尝试过:

  • a schema actually existing in tempdb called blat 实际存在于tempdb中的模式,称为blat
  • the table blat.#pound created by a user whose default schema is blat table blat.#pound由默认架构为blat的用户创建
  • both of the above 以上都是

In all three cases, the same results as above were achieved. 在所有三种情况下,都获得了与上述相同的结果。

You also can't create two #temp tables with the same name in different schemas: 您也不能在不同的模式中创建两个具有相同名称的#temp表:

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

Result: 结果:

Msg 2714, Level 16, State 6 Msg 2714,Level 16,State 6
There is already an object named '#flab' in the database. 数据库中已经有一个名为'#flab'的对象。

This is not a parsing problem (like many #temp table issues are); 这不是解析问题(就像许多#temp表问题一样); you can run those two statements separately and receive the same error. 您可以单独运行这两个语句并收到相同的错误。

So, this is a long-winded way of saying, you don't ever need to specify the schema when resolving a #temp table name, it will always be created under dbo and resolution at least under OBJECT_ID will ignore the schema you specify ( OBJECT_SCHEMA_NAME also always returns dbo when run in the context of #tempdb, but not in any other database). 所以,这是一个冗长的说法,你不需要在解析#temp表名时指定模式,它总是在dbo下创建,至少在OBJECT_ID下的解析将忽略你指定的模式( OBJECT_SCHEMA_NAME在#tempdb的上下文中运行时也总是返回dbo ,但在任何其他数据库中都没有。 All bets are off if you try to query schema_id in tempdb.sys.objects . 所有的赌注都关闭,如果你尝试查询schema_idtempdb.sys.objects

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;

Temp table defined that way will exist as long as the connection that created it is open. 只要创建它的连接打开,就会存在以这种方式定义的临时表。 Usually there's no need to check if it exists or drop it manually because you have full control inside your connection, but if you really need to check it you can check for tempdb.dbo.#tempTable. 通常不需要检查它是否存在或者手动丢弃它,因为你在连接中有完全的控制权,但如果你真的需要检查它,你可以检查tempdb.dbo。#tempTable。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM