Si bien la respuesta de Brent es correcta para todos los fines prácticos, y esto no es algo por lo que haya visto preocuparse a alguien, es posible que múltiples invocaciones de un procedimiento almacenado en una sesión se afecten entre sí a través de una tabla #temp con ámbito de sesión .
La buena noticia es que es extremadamente improbable que suceda en la naturaleza porque
1) Las tablas #Temp declaradas dentro de un procedimiento almacenado o lotes anidados en realidad no tienen visibilidad de sesión (o duración). Y estos son, con mucho, el caso más común.
2) Requiere MultipleActiveResultsets y alguna programación de cliente asíncrono muy extraña, o para que el procedimiento almacenado devuelva un conjunto de resultados en el medio, y el cliente llame a otra instancia del procedimiento almacenado mientras procesa los resultados desde el primero.
Aquí hay un ejemplo artificial:
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();
}
}
}
que salidas
Numer of rows in temp table 0
Hit any key to exit
porque la segunda invocación del procedimiento almacenado insertó una fila y luego eliminó todas las filas de #t mientras la primera invocación esperaba que el cliente recuperara las filas de su primer conjunto de resultados. Tenga en cuenta que si el primer conjunto de resultados es pequeño, las filas podrían quedar almacenadas en el búfer y la ejecución podría continuar sin enviar nada al cliente.
Si mueves el
create table #t(id int)
en el procedimiento almacenado que produce:
Numer of rows in temp table 1
Hit any key to exit
Y con la tabla temporal declarada dentro del procedimiento, si cambia la segunda consulta a
cmd2.CommandText = "select * from #t";
Falla con:
'Nombre de objeto inválido' #t '.'
Porque una tabla #temp creada dentro de un procedimiento almacenado o lote anidado solo es visible en ese procedimiento almacenado o lote y en procedimientos anidados y lotes que llama, y se destruye cuando finaliza el procedimiento o lote.