【问题标题】:Temp table parsing - SQL bug - Explanation needed临时表解析 - SQL 错误 - 需要说明
【发布时间】:2020-02-05 00:49:41
【问题描述】:

我有以下无法执行的代码。我不是在寻找解决方法。我想了解 SQL 在做什么以及为什么它会因错误而失败:“数据库中已经有一个名为 '#t' 的对象。”请注意解释。

if object_id('tempdb.dbo.#t') is not null

drop table #t

GO

declare @i int = 0

if @i = 0

create table #t (col1 int)

else

create table #t (col1 int)

【问题讨论】:

  • 如果您添加了 sql 标签和您正在使用的特定 DBMS 的标签,将会很有帮助。
  • 蒂肯。我刚刚做了
  • 这正是您要执行的脚本吗?
  • 没有。这是完整脚本的简化。完整的脚本没有意义。错误是一样的
  • 这是对编译工作方式的限制。有条件地创建临时表充满了危险,因为优化器确实需要知道该表是否存在(及其模式)来为引用它的语句生成执行计划,所以#t 在任何地方仍然被认为是“相同的”表它发生了,因此不允许重复的CREATEs(与其他不兼容的 DDL 语句一样)。大致上,根本不要这样做。保持您的临时表方案不变,不要有条件地创建它们。 FWIW,你可以有条件地ALTER他们。

标签: sql sql-server temp-tables


【解决方案1】:
-checking Temp table is exists , if Exists then Drop the table
  IF OBJECT_ID('TEMPDB.DBO.#t') IS NOT NULL DROP TABLE #t

 --Declaring Variable @i and assigning value 0
   DECLARE @i int = 0
  --Checking @i = 0 or not
  IF @i = 0
  BEGIN
      -- if @i value is 0 
      CREATE TABLE #t (col1 int)

  END
  GO
  --checking Temp table is exists , if Exists then Drop the table

   IF OBJECT_ID('TEMPDB.DBO.#t') IS NOT NULL DROP TABLE #t
   --Declaring Variable @i and assigning value 1

    DECLARE @i int = 1 --  Checking @i = 1
  IF @i= 1
  BEGIN    
        -- if @i value is not 0 
         CREATE TABLE #t (col1 int)
  END
  GO

【讨论】:

  • 请检查您的代码并尝试运行。它不编译。错误是:“数据库中已经有一个名为 '#t' 的对象。”我得到了同样的结果。
  • 这是一个限制。动态 SQL 也不起作用,因为 #tmp 将在新会话中创建并立即丢失。
  • 到目前为止,由于 SQL 提供的错误不正确也不正确,这是 TEMPDB 中不需要的编译行为导致错误。
【解决方案2】:

我建议为临时表使用不同的名称。

至少如果你真的需要在IFELSE 中创建临时表。

或者在开始时只删除和创建一次临时表,在 IF 之前。

可悲的是,编译器对这种小事感到困惑。
当 T-Sql 被解析和评估时,它会忽略控制流语句,如IF
所以同一个临时表的创建在同一个范围内被看到,并被评估为重复对象问题。

解决方法示例:

declare @i int = 0

if @i = 0
 begin
   if object_id('tempdb..#t1') is not null
     drop table #t1;
   create table #t1 (col1 int);
 end
else
  begin
    if object_id('tempdb..#t2') is not null
       drop table #t2;
    create table #t2 (col1 int, col2 int);
  end

【讨论】:

  • 谢谢卢克。我最终在我的代码中做了类似的事情。但不是在寻找解决方法。想了解为什么 SQL 返回无效消息并获得错误行为。到目前为止,这是因为编译器在 TEMPDB 中感到困惑和错误。如果在用户表中创建表,则不会发生(删除#)
  • 也没有找到官方原因。只是 this 旧 SO 帖子。
  • 谢谢卢克。是的。看来那个人也有类似的问题。有可用的解决方法。只是想了解到底发生了什么。赞赏。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
相关资源
最近更新 更多