SQL Server - 在TRY和CATCH中使用“If ... Then”删除临时表

问题描述 投票:2回答:2

谁能解释为什么这段代码会导致错误?

BEGIN TRY
    IF OBJECT_ID ('TEMPDB..#ABC') IS NOT NULL 
    BEGIN
        DROP TABLE #ABC
    END;

    SELECT 1 AS A, 2 AS B 
    INTO #ABC;
END TRY
BEGIN CATCH
END CATCH;

DROP TABLE #ABC;

BEGIN TRY
    IF OBJECT_ID ('TEMPDB..#ABC') IS NOT NULL 
    BEGIN
        DROP TABLE #ABC
    END;

    SELECT 3 AS C, 4 AS D 
    INTO #ABC;
END TRY
BEGIN CATCH
END CATCH;

SELECT * FROM #ABC;

错误发生在第二个TRY和CATCH语句中,显示#ABC表已存在,即使在第二个TRY块之前有一个drop语句,甚至在第二个TRY内,还有一个“IF OBJECT_ID ... THEN DROP”语句。

Msg 2714,Level 16,State 1,XX行 数据库中已经有一个名为#ABC的对象

sql sql-server
2个回答
1
投票

您需要在两个块之间使用“GO”,否则SQL Server将尝试将整个语句集作为单个实体执行。

因为第一部分中有DDL,所以在解析第二个语句时不会执行它。通过在第一个CATCH结束后放置“GO”,脚本应该执行正常。


1
投票

在一个批处理中你有两个INTO #ABC所以在编译sql server时不考虑它们在什么条件下创建它只是抛出错误,认为你试图创建两次相同的表。

BEGIN TRY
  BEGIN
     IF OBJECT_ID ('TEMPDB..#ABC') IS NOT NULL 
     DROP TABLE #ABC
     create table #ABC(A tinyint, b tinyint, c tinyint, d tinyint)
  END;
  Insert into #ABC(A, B)
  SELECT 1 AS A, 2 AS B 

END TRY
BEGIN CATCH
END CATCH;

BEGIN TRY
  Insert into #ABC(C, D)
  SELECT 3 AS C, 4 AS D 

END TRY
BEGIN CATCH
END CATCH;

SELECT * FROM #ABC;

如果你不想在结果中有4列,那么创建两个中间临时表并将结果插入到中间临时表中,并将两个表的结果插入到#ABC

© www.soinside.com 2019 - 2024. All rights reserved.