【问题标题】:SQL Server - Dropping Temporary Table using "If ... Then" inside TRY and CATCHSQL Server - 在 TRY 和 CATCH 中使用“If ... Then”删除临时表
【发布时间】:2018-06-06 01:08:57
【问题描述】:

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

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 "声明。

消息 2714,第 16 级,状态 1,第 XX 行
数据库中已经有一个名为#ABC的对象

【问题讨论】:

  • 我想知道 - 您是否使用了一些奇怪的 SQL Server SKU,您必须为使用的每个唯一名称支付额外的许可费用?临时表名称最长可达 116 个字符 - 为什么这里的两个临时表都使用 same 名称如此重要?

标签: sql sql-server


【解决方案1】:

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

因为第一段有DDL,所以在解析第二条语句的时候并没有执行。通过在第一个 CATCH 结束后放置一个“GO”,脚本应该可以正常执行。

【讨论】:

    【解决方案2】:

    在一个批次中,您有两个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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-15
      • 1970-01-01
      • 2017-06-08
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 2020-06-19
      相关资源
      最近更新 更多