图像#1:我正在创建一个用于将记录插入#t1
的存储过程。
在同一个会话中,我执行Localtemp1存储过程任意次,它工作正常:
图像#2:再次在另一个会话中执行存储过程&工作得很好:
图像#3:现在创建用于将记录插入##tt
的存储过程。对于第一次执行globaltemp1存储过程,它运行良好:
图像#4:但是当我第二次执行它时,它显示错误(在DB中不存在):
图像#5:然后我关闭了创建globaltemp存储过程的会话,并且在新的会话中,我执行了存储过程,并且它第一次运行良好:
图片#6:但是当我第二次执行它时,它再次显示错误(在DB中不存在):
我所知道的是当地温度和范围全局临时,但在存储过程中,它们是完全不同的
有人可以告诉我
多次执行localtemp1存储过程会产生输出,但第一次执行globaltemp1 sp会产生输出,第二次会导致错误
据我所知,执行存储过程后temptable被删除。那么为什么localtemp1存储过程会在所有会话中执行多次?
为什么globaltemp1存储过程执行一次,第二次显示错误?
最后一个,Globaltemp存储过程仅在创建会话关闭时首次显示另一个会话中的输出
我的意思是
我是SQL的初学者,拜托,有人让我明白,因为如果我找不到逻辑&正确的理由我无法深入探讨另一个话题。
答案 0 :(得分:4)
临时表的概念是暂时保存记录。它是某种类型的数组,您可以使用相同的变量存储多个记录。
创建临时表时,实际上它是在相应服务器的tempdb中创建的。即使您将其命名为#temp,在tempdb上创建它的名称也会有一些额外的参数,例如创建表的数据库名称和会话ID等。
我刚刚在master数据库中创建了以下临时表
这就是它在tempdb中的命名方式
仍然,在我的数据库中,我可以使用名称#temp访问它。但是这种临时表的局限性在于它们是本地的,只能从该会话访问,所以如果我尝试从任何其他查询窗口(会话)访问这个#temp,即使在同一个数据库中也是如此,我将无法访问它。这就是我们使用全局临时表的地方。因此,如果我在表名中再添加一个#,那么它就会成为全局临时表,可以跨会话访问。它仍然在Tempdb上创建,但是像这样
每当您关闭查询窗口/会话时,都会自动删除本地和全局临时表。
因此,在存储过程的情况下,sp的开始和结束时间被视为一个会话。因此,一旦sp执行完成,就会删除在sp内创建的所有临时表。因此,您不能使用一个SP在另一个SP中创建的临时表。
希望这有帮助
答案 1 :(得分:1)
本地临时表仅在当前会话中可见,全局临时表对所有会话都可见。当创建表的会话结束并且所有其他任务已停止引用它们时,将自动删除全局临时表。任务和表之间的关联仅在单个Transact-SQL语句的生命周期内维护。这意味着在创建会话结束时主动引用该表的最后一个Transact-SQL语句完成时,将删除全局临时表。
答案 2 :(得分:0)
如果您必须拥有全局临时表,那么最佳解决方案是创建永久表,然后将表放在存储过程的末尾。您可以在创建之前检查它是否存在:
如果OBJECT_ID('dbo.yourtablenamehere','U')不是NULL DROP TABLE dbo.yourtablenamehere;
临时表与永久表之间的差异实际上并没有太大差异,主要是临时表自动丢失。如果您在调用此过程的应用程序中使用它,则最好让应用程序将临时表加载到数组中并为您进行比较,因为它可以在执行和重新执行存储过程时维护该数组。 / p>
答案 3 :(得分:0)
有充分的理由写一个临时表而不是创建一个表然后删除它...访问权限。如果您要创建只供只读权限的人使用的表,则他们将无法创建表。