Tre*_*ngs 16 sql-server sql-server-2012
我编写了一个使用临时表的存储过程。我知道在 SQL Server 中,临时表是会话范围的。但是,我无法找到有关会话确切功能的确切信息。特别是,如果此存储过程可以在单个会话中并发执行两次,则该过程中的事务需要显着更高的隔离级别,因为这两个执行现在共享一个临时表。
Dav*_*oft 19
而布伦特的答案是对所有的实际目的是正确的,这是不是我见过某人担心,这是可以在会话存储过程中的多次调用通过会话范围#TEMP表互相影响.
好消息是这极不可能发生在野外,因为
1) 在存储过程或嵌套批处理中声明的#Temp 表实际上没有会话可见性(或生命周期)。这些是迄今为止最常见的情况。
2)它需要MultipleActiveResultsets和一些非常奇怪的异步客户端编程,或者存储过程在中间返回一个结果集,客户端在处理第一个结果时调用存储过程的另一个实例。
这是一个人为的例子:
using System;
using System.Data.SqlClient;
namespace ado.nettest
{
class Program
{
static void Main(string[] args)
{
using (var con = new SqlConnection("Server=localhost;database=tempdb;integrated security=true;MultipleActiveResultSets = True"))
{
con.Open();
var procDdl = @"
create table #t(id int)
exec ('
create procedure #foo
as
begin
insert into #t(id) values (1);
select top 10000 * from sys.messages m, sys.messages m2;
select count(*) rc from #t;
delete from #t;
end
');
";
var cmdDDL = con.CreateCommand();
cmdDDL.CommandText = procDdl;
cmdDDL.ExecuteNonQuery();
var cmd = con.CreateCommand();
cmd.CommandText = "exec #foo";
using (var rdr = cmd.ExecuteReader())
{
rdr.Read();
var cmd2 = con.CreateCommand();
cmd2.CommandText = "exec #foo";
using (var rdr2 = cmd2.ExecuteReader())
{
}
while (rdr.Read())
{
}
rdr.NextResult();
rdr.Read();
var rc = rdr.GetInt32(0);
Console.WriteLine($"Numer of rows in temp table {rc}");
}
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
哪个输出
Numer of rows in temp table 0
Hit any key to exit
Run Code Online (Sandbox Code Playgroud)
因为存储过程的第二次调用插入了一行,然后从#t 中删除了所有行,而第一次调用正在等待客户端从其第一个结果集中获取行。请注意,如果第一个结果集很小,则行可能会被缓冲并且可以继续执行而不向客户端发送任何内容。
如果你移动
create table #t(id int)
Run Code Online (Sandbox Code Playgroud)
进入它输出的存储过程:
Numer of rows in temp table 1
Hit any key to exit
Run Code Online (Sandbox Code Playgroud)
并与临时表声明中的程序,如果你改变了第二次查询
cmd2.CommandText = "select * from #t";
Run Code Online (Sandbox Code Playgroud)
它失败了:
'无效的对象名称'#t'。'
因为在存储过程或嵌套批处理中创建的 #temp 表仅在该存储过程或批处理以及它调用的嵌套过程和批处理中可见,并且在过程或批处理结束时被销毁。
Bre*_*zar 12
不能同时进行。您的选择包括: