Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL临时表的作用域仅限于进程_Sql_Sql Server - Fatal编程技术网

SQL临时表的作用域仅限于进程

SQL临时表的作用域仅限于进程,sql,sql-server,Sql,Sql Server,我需要创建一个表,其中包含许多只作用于正在运行的存储过程的索引 我尝试了一个表变量,但它似乎不支持索引。本地临时表似乎创建了一个“真实”表,需要在进程结束时显式删除,从中我推断它也在并发运行中共享,因此会中断 我可以使用什么来存储索引范围仅限于运行存储过程的单个实例的数据?您不必担心删除表。SQL Server会自动执行此操作。正如报告中所述: 在存储过程中创建的本地临时表将在存储过程完成时自动删除。这张桌子可以放在桌子上 由存储程序执行的任何嵌套存储过程引用 创建表的过程。无法引用该表 调用

我需要创建一个表,其中包含许多只作用于正在运行的存储过程的索引

我尝试了一个表变量,但它似乎不支持索引。本地临时表似乎创建了一个“真实”表,需要在进程结束时显式删除,从中我推断它也在并发运行中共享,因此会中断


我可以使用什么来存储索引范围仅限于运行存储过程的单个实例的数据?

您不必担心删除表。SQL Server会自动执行此操作。正如报告中所述:

  • 在存储过程中创建的本地临时表将在存储过程完成时自动删除。这张桌子可以放在桌子上 由存储程序执行的任何嵌套存储过程引用 创建表的过程。无法引用该表 调用创建表的存储过程的进程
这是访问临时表的作用域规则的结果

我承认,在实践中,我倾向于在存储过程中显式地删除临时表。以下方面的差异:

  • create table temp
  • create table#temp
  • create table##temp

它们都太相似了,无法依赖第二个会自动删除,但第一个和第三个不会。但是,这是我的“问题”,不是最佳做法。

更新

答案是根本不用担心,因为temp表就像存储过程中的局部变量一样

我想确定我的怀疑是否正确,所以我做了这个测试

create procedure TestTempData
as
begin
    declare @date datetime = getdate()
    if object_id('#testing') is not null
        drop table #testing
    create table #testing(
        Id int identity(1,1),
        [Date] datetime
    )

    print 'run at ' + format(@date,'HH:mm:ss')

    insert into #testing([Date]) values
    (dateadd(second,10,getdate())),
    (dateadd(second,20,getdate())),
    (dateadd(second,30,getdate()))
    waitfor delay '00:00:15'
    select * from #testing
end
然后我运行了这个查询

exec TestTempData

waitfor delay '00:00:02'

exec TestTempData
结果是

run at 14:57:39
Id  Date
1   2016-09-21 14:57:49.117
2   2016-09-21 14:57:59.117
3   2016-09-21 14:58:09.117
第二个结果

run at 14:57:56
Id  Date
1   2016-09-21 14:58:06.113
2   2016-09-21 14:58:16.113
3   2016-09-21 14:58:26.113
如果并发运行将影响#temp表,则两个结果 应该是相同的,不是这样的,似乎温度 存储过程中的表的作用类似于存储过程中的局部变量 方法

在与Gordon Linoff聊天之前

由于您提到临时表是跨并发运行共享的,因此您的临时表对于当前运行应该是唯一的

您的存储过程应该如下所示

create procedure YourProc(@userId int)
as
begin
   if object_id('#temp' + @userId) IS NOT NULL
       execute( 'DROP TABLE #temp' + @userId +'')
    ...
    execute('insert into #temp' + @userId + 'values(...')
end
上述解决方案将确保不会发生冲突,也不会丢失数据,因为每个用户ID的每次执行都是唯一的

您不需要在完成时删除该表,因为它会自动删除该表


希望这能帮助您

本地临时表(单前缀)适用于当前连接,不会与并发会话冲突。表变量确实支持主键和唯一约束,并且在SQL 2014和更高版本中支持索引。我认为他应该担心,如果创建的临时表上有一些插入和更新,然后,当进程尚未完成时,存储过程又发生了另一次调用!?我认为最好的方法是使用#temp+UserKey组合,但他需要动态运行queries@HadiHassan . . . 阅读文档。SQL Server可防止出现这种情况。事实上,临时表名的长度(116个字符)令人尴尬,而常规表的长度为128个字符。:P我不应该与0.5米的表名争论!!,我用一个测试更新了我的答案,您是对的,似乎存储过程中的temp表的行为类似于localvariable@GordonLinoff我会再来一次。我的测试不在存储过程中,因此这可以解释脚本运行后它的持久性。