检查是否存在临时表,并在创建临时表之前删除它是否存在

Sri*_*har 637 sql-server sql-server-2005 alter-table temp-tables

我正在使用以下代码检查临时表是否存在,如果存在,则在再次创建之前删除该表.只要我不更改列,它就可以正常工作.如果我稍后添加一列,则会显示错误"无效列".请让我知道我做错了什么.

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

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
)

select company, stepid, fieldid from #Results

--Works fine to this point

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

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
    NewColumn            NVARCHAR(50)
)

select company, stepid, fieldid, NewColumn from #Results

--Does not work
Run Code Online (Sandbox Code Playgroud)

小智 696

我无法重现错误.

也许我不理解这个问题.

以下在SQL Server 2005中对我来说很好,在第二个选择结果中出现了额外的"foo"列:

IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
CREATE TABLE #Results ( Company CHAR(3), StepId TINYINT, FieldId TINYINT )
GO
select company, stepid, fieldid from #Results
GO
ALTER TABLE #Results ADD foo VARCHAR(50) NULL
GO
select company, stepid, fieldid, foo from #Results
GO
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
GO
Run Code Online (Sandbox Code Playgroud)

  • @ Conrad.Dean double dot是.dbo的缩写. (77认同)
  • @deutschZuid更准确地说双点是用户的默认架构,通常是dbo(这不是一个好主意,使dbo成为用户的默认架构,但通常是这样) (31认同)
  • `'tempdb ..#name'`正是我所需要的.我正在使用''dbo.#name'`,就像一个傻瓜.我得到了`tempdb`部分,但双点有什么用? (28认同)
  • 你的代码与OP有很大的不同,你的"无法重现"的陈述毫无意义.我很高兴你能以不同的方式工作. (8认同)
  • IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results` CREATE TABLE #Results (Company CHAR(3),StepId INT) select company, stepid from #results 现在回到 create 语句并添加一个在最后的列 fieldid.change select 语句以包含 fieldid 并运行它。 (2认同)

小智 79

声明应该是订单

  1. 更改表的声明
  2. 选择声明.

如果没有'GO',整个事物将被视为一个单独的脚本,当select语句查找列时,将无法找到它.

使用"GO",它会将脚本的一部分视为"GO"作为一个批处理,并在"GO"之后进入查询之前执行.

  • 这应该标记为正确的答案.这并不是说SELECT实际上要在create table之前运行,而是它正在被解析并在运行之前抛出一个错误,因为有一个名为#Results的现有表还没有在FieldId列中解析select语句的时间.在那里添加GO将查询分成批处理,每个批处理都是单独解析和运行的. (7认同)
  • 我无法相信这个答案与最佳答案之间的投票差异,它改变了代码这么多 - 没有解释原因 - 作为回应毫无意义。 (3认同)

Pரத*_*ீப் 55

相反的dropping,并重新创建临时表,你可以truncate和重用

IF OBJECT_ID('tempdb..#Results') IS NOT NULL
    Truncate TABLE #Results
else
    CREATE TABLE #Results
    (
        Company             CHAR(3),
        StepId              TINYINT,
        FieldId             TINYINT,
    )
Run Code Online (Sandbox Code Playgroud)

如果您正在使用Sql Server 2016Azure Sql Database使用以下语法删除临时表并重新创建它.更多信息在这里MSDN

句法

DROP TABLE [IF EXISTS] [database_name.[schema_name].| schema_name.] table_name [,... n]

查询:

DROP TABLE IF EXISTS tempdb.dbo.#Results
CREATE TABLE #Results
  (
   Company             CHAR(3),
   StepId              TINYINT,
   FieldId             TINYINT,
  )
Run Code Online (Sandbox Code Playgroud)

  • 没关系.我现在意识到,SQL Server 2008支持"DROP TABLE",但2016年引入了"IF EXISTS"条款. (4认同)
  • 从技术上讲,如果临时表已存在,则无法保证表的架构匹配。可能是相同的,但您可能已经对表执行了其他操作,特别是如果您使用“#Results”、“#Products”或“#Customers”等通用名称。这是我使用 drop/create 而不是 truncate 的主要原因。 (3认同)

vik*_*kas 51

我认为问题是您需要在两者之间添加GO语句以将执行分成批处理.作为第二个drop脚本,即IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results没有删除临时表是单个批处理的一部分.你能试试下面的剧本吗?

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

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
)

GO

select company, stepid, fieldid from #Results

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

CREATE TABLE #Results
(
    Company                CHAR(3),
    StepId                TINYINT,
    FieldId                TINYINT,
    NewColumn            NVARCHAR(50)
)

GO

select company, stepid, fieldid, NewColumn from #Results
Run Code Online (Sandbox Code Playgroud)


use*_*628 28

这对我有用: social.msdn.microsoft.com/Forums/en/transactsql/thread/02c6da90-954d-487d-a823-e24b891ec1b0?prof=required

if exists (
    select  * from tempdb.dbo.sysobjects o
    where o.xtype in ('U') 

   and o.id = object_id(N'tempdb..#tempTable')
)
DROP TABLE #tempTable;
Run Code Online (Sandbox Code Playgroud)

  • 这只是条件表删除的不同语法。这很有趣,但没有解决OP的问题,而且大部分都是多余的。如果您只检查 OBJECT_ID(N'tempdb..#Results') 不为空,那么就足以证明该对象已经存在。 (2认同)

Iva*_*vak 19

只是我身边的一点评论,因为这OBJECT_ID对我不起作用.它总是会返回

`#tempTable不存在

..尽管确实存在.我发现它存储了不同的名称(后缀为_下划线),如下所示:

#tempTable________

这适合我:

IF EXISTS(SELECT [name] FROM tempdb.sys.tables WHERE [name] like '#tempTable%') BEGIN
   DROP TABLE #tempTable;
END;
Run Code Online (Sandbox Code Playgroud)

  • 警告:如果表是由任何线程创建的,该代码将检测该表.单个#temp表是根据存储过程的每个线程/调用者单独创建的,这就是为什么名称中的下划线使每个线程/进程存在不同的副本.只要您使用的是SQL 2005或更高版本,Object_ID就可以正常运行当前线程. (6认同)

小智 17

只需一行代码即可完成:

IF OBJECT_ID('tempdb..#tempTableName') IS NOT NULL DROP TABLE #tempTableName;   
Run Code Online (Sandbox Code Playgroud)

  • 我必须每天看看这个 (4认同)

gbn*_*gbn 10

pmac72正在使用GO将查询分解为批处理并使用ALTER.

您似乎正在运行相同的批处理,但在更改后运行它两次:DROP ... CREATE ... edit ... DROP ... CREATE ..

也许发布您的确切代码,以便我们可以看到发生了什么.


DSR*_*DSR 10

这对我有用,

IF OBJECT_ID('tempdb.dbo.#tempTable') IS NOT NULL 
DROP TABLE #tempTable; 
Run Code Online (Sandbox Code Playgroud)

这里 tempdb.dbo(dbo 只不过是你的架构) 更重要。


Oth*_*ali 8

现在,如果您使用的是SQL Server(2016+)的新版本之一,则可以使用以下语法。

DROP TABLE IF EXISTS schema.yourtable(even temporary tables #...)
Run Code Online (Sandbox Code Playgroud)

  • @StingyJack因为SQL语法与SSMS版本无关,但与SQL Server版本相关。SQL Server 2016中提供了“ IF [NOT] EXISTS”子句。使用哪个SSMS版本都没有关系。 (6认同)

All*_*n F 8

注意:这也适用于 ## 临时表。

IE

IF OBJECT_ID('tempdb.dbo.##AuditLogTempTable1', 'U') IS NOT NULL
DROP TABLE ##AuditLogTempTable1
Run Code Online (Sandbox Code Playgroud)

注意:这种类型的命令仅适用于 SQL Server 2016 之后的版本。问问自己..我是否还有仍在使用 SQL Server 2012 的客户?

DROP TABLE IF EXISTS ##AuditLogTempTable1
Run Code Online (Sandbox Code Playgroud)


小智 7

我已经创建临时表时通常会遇到此错误; 检查SQL语句是否有错误的代码会看到"旧"临时表,并返回后续语句中列数的错误计数,就像从未删除临时表一样.

在创建具有较少列的版本后更改临时表中的列数后,删除表,然后运行查询.


ano*_*xen 5

我最近看到DBA做了类似的事情:

begin try
    drop table #temp
end try

begin catch 
    print 'table does not exist'
end catch 

create table #temp(a int, b int)
Run Code Online (Sandbox Code Playgroud)

  • 该try语句将捕获尝试删除表时可能发生的其他错误。该代码假定尝试失败的唯一原因是因为该表不存在。它可能在大多数时间都有效,但我不能保证。如果try语句由于其他原因而失败,则在创建表时会出现错误,因为这掩盖了删除表的实际问题。 (2认同)